Skip to main content

GenericTimer

Struct GenericTimer 

Source
pub struct GenericTimer { /* private fields */ }
Available on neither armv6 nor crate feature bcm2712.
Expand description

The per-core ARM generic (architected) timer, driving the non-secure physical timer (CNTP).

A zero-sized handle: it owns no peripheral token because the generic timer is CPU state, not an MMIO peripheral, and every method acts on the core it is called from. A GenericTimer obtained on core 0 configures core 0’s timer; one obtained inside a secondary core’s entry point configures that core’s. Re-arming from an interrupt handler (as the examples do) is exactly this pattern – construct one and act on the core currently taking the interrupt.

Implementations§

Source§

impl GenericTimer

Source

pub fn new() -> Self

Creates a handle to the calling core’s generic timer. Needs no configuration – the counter is already free-running from boot.

Source

pub fn frequency(&self) -> u32

The counter frequency in Hz, as programmed by the firmware (CNTFRQ) – 19.2 MHz on this hardware. Used to convert between microseconds and counter ticks.

Source

pub fn now(&self) -> u64

The current 64-bit physical count (CNTPCT) – a monotonic tick count since the counter started, at frequency ticks per second. The architected read is atomic, so unlike the System Timer’s split CLO/CHI this needs no re-read guard.

Source

pub fn delay_us(&self, us: u32)

Busy-waits for approximately us microseconds against the counter. Independent of the System Timer peripheral, so a core that doesn’t own SYSTMR can still delay.

Source

pub fn delay_ms(&self, ms: u32)

Busy-waits for approximately ms milliseconds against the counter.

Source

pub fn arm_after_us(&self, us: u32)

Arms the physical timer to fire us microseconds from now and enables it (CNTP_TVAL <- us in ticks, CNTP_CTL.ENABLE <- 1).

Also the way to acknowledge a fired tick: the interrupt is level-sensitive on CNTP_CTL.ISTATUS, so re-arming past the current count is what deasserts it – there is no write-1-to-clear. Calling this from the handler both acks the tick just taken and schedules the next one.

CNTP_TVAL is a 32-bit signed down-counter, so the interval is bounded (~111 s at 19.2 MHz); for longer or drift-free periods use set_deadline against an absolute now-based deadline instead.

Source

pub fn set_deadline(&self, deadline: u64)

Arms the physical timer to fire when the count reaches the absolute deadline (CNTP_CVAL <- deadline, in the same units as now) and enables it.

This is the drift-free primitive an executor wants: advancing the deadline by a fixed period each tick (set_deadline(deadline += period)) keeps the cadence pinned to the counter rather than to when the handler happened to run, and the full 64-bit comparator removes the interval bound arm_after_us has.

Source

pub fn is_pending(&self) -> bool

True if the timer condition is currently met (CNTP_CTL.ISTATUS) – i.e. this timer is the source asserting an interrupt. Lets a handler tell the generic timer apart from other sources without reading the ARM-local controller’s IRQ-source register.

Source

pub fn disable(&self)

Stops the timer (CNTP_CTL.ENABLE <- 0). The counter keeps running – now is unaffected – but no further interrupt is raised until it is armed again.

Source

pub fn route_irq(&self)

Routes this core’s non-secure physical timer IRQ (CNTPNSIRQ) to the core through the ARM-local interrupt controller – the second of the three gates (see the module doc comment). Per-core: it programs the control register belonging to whichever core calls it.

Source

pub fn mask_irq(&self)

Masks this core’s physical timer IRQ at the ARM-local interrupt controller – the inverse of route_irq.

Trait Implementations§

Source§

impl Default for GenericTimer

Source§

fn default() -> Self

Source§

impl DelayNs for GenericTimer

Source§

fn delay_ns(&mut self, ns: u32)

Busy-waits ns nanoseconds against the counter, rounding the tick count up so a nonzero request always waits at least one tick.

Source§

fn delay_us(&mut self, us: u32)

Delegates to the inherent GenericTimer::delay_us.

Source§

fn delay_ms(&mut self, ms: u32)

Delegates to the inherent GenericTimer::delay_ms.

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 = !

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

fn try_from(value: U) -> Result<T, !>

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.