pub struct SpscFrameRing<const N: usize, const BYTES: usize> { /* private fields */ }Expand description
A fixed-capacity SPSC FIFO of BYTES-sized frames for the ISR-to-pipeline
capture hand-off. N slots live inline (no alloc); usable capacity is
N - 1 (one slot separates a full ring from an empty one), so N >= 2, and
N >= 3 gives a double-buffer plus one frame in flight.
Implementations§
Source§impl<const N: usize, const BYTES: usize> SpscFrameRing<N, BYTES>
impl<const N: usize, const BYTES: usize> SpscFrameRing<N, BYTES>
Sourcepub const fn new() -> Self
pub const fn new() -> Self
Build an empty ring. const, so it lives in a static (the DMA-ring
idiom) shared between the producer ISR and the consumer. N >= 2.
Sourcepub fn overruns(&self) -> u32
pub fn overruns(&self) -> u32
Full-ring events: produce calls that found no free
slot. For the canonical ISR producer (one attempt per frame, no retry)
this is the count of frames dropped to back-pressure.
Sourcepub fn produce(
&self,
fill: impl FnOnce(&mut [u8; BYTES]),
) -> Result<(), Overrun>
pub fn produce( &self, fill: impl FnOnce(&mut [u8; BYTES]), ) -> Result<(), Overrun>
PRODUCER side (call from exactly one context, e.g. a DMA-completion ISR):
fill the next free slot via fill and publish it to the consumer.
Returns Err(Overrun) if the ring is full (the consumer is behind): the
frame is dropped and counted, never blocked on, because a producer in an
interrupt cannot wait.
Sourcepub fn borrow(&self) -> Option<SystemSlice>
pub fn borrow(&self) -> Option<SystemSlice>
CONSUMER side: borrow the oldest published frame zero-copy as a
SystemSlice, or None if the ring is empty. The borrow aliases the
ring slot (no copy); it stays valid until release
advances past it.
Contract: borrow at most one frame at a time and [release] it before the
next borrow, after the frame (and its slice) is dropped, the single-frame-
in-flight discipline the static runners already follow (each frame is
dropped before the next next()). Releasing a still-referenced slice
would let the producer reuse the slot under the reader.
Not built under --cfg loom: the lend hands out a raw pointer that
outlives any scoped cell access, which loom’s UnsafeCell cannot model.
The loom consumer reads through [Self::loom_peek0] instead.