Skip to main content

SecureSerialResources

Struct SecureSerialResources 

Source
pub struct SecureSerialResources<M: RawMutex + 'static, const N_INFLIGHT: usize, const N_RX_POOL: usize, const N_BUF: usize> { /* private fields */ }
Expand description

Queues and pools for crate::run_read, crate::run_write, and crate::SecureSerialSender on a single endpoint (one UART side).

This type groups the TX chunk pool, TX/RX embassy_sync::channel::Channels, and the RX reassembly pool so you do not wire six separate static items by hand.

§Sizes

  • N_INFLIGHT: capacity of the outgoing chunk queue, TX BufferPool, and ACK channels (same as in-flight chunk/ACK window); must be in 1..=32.
  • N_RX_POOL: number of parallel RX packet buffers and RX completion queue depth (1..=32).
  • N_BUF: byte length of each RX reassembly buffer (must fit your largest packet).

BufferPool and channels require fixed sizes in that range.

§static placement

embedded_buffer_pool::BufferPool only exposes take / try_take on &'static pools. Put this struct in a static_cell::StaticCell (or another 'static slot) so references passed to crate::SecureSerialSender::new and async tasks are valid for the whole program.

§Example (Cortex-M / no_std)

Store the bundle once in a static_cell::StaticCell, then reborrow it as a shared &'static SecureSerialResources<...> so every task can hold a copy of the pointer (the mutex-backed channels inside are safe to share). Use SecureSerialResourcesDefault if the default sizes (8 TX slots, 4 × 4096-byte RX buffers) fit your link.

use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
use embassy_executor::Spawner;
use static_cell::StaticCell;
use secure_serial::{SecureSerialResources, SecureSerialResourcesDefault};

static SERIAL_RES: StaticCell<SecureSerialResourcesDefault<CriticalSectionRawMutex>> =
    StaticCell::new();

fn init_serial_tasks(spawner: Spawner) {
    let res_mut = SERIAL_RES.init(SecureSerialResourcesDefault::new());
    let res: &'static SecureSerialResourcesDefault<CriticalSectionRawMutex> = res_mut;

    // `tx_pool()` and channel endpoints are valid for `'static` because `res` is.
    let mut tx_rx = res.tx_chunks_receiver();
    let mut acks_out_rx = res.acks_to_wire_receiver();
    unwrap!(spawner.spawn(run_write_task(&mut tx_rx, &mut acks_out_rx)));
    unwrap!(spawner.spawn(run_read_task(res)));
    unwrap!(spawner.spawn(app_task(res)));
}

#[embassy_executor::task]
async fn run_write_task(
    tx_rx: &mut /* `Receiver` for DATA chunks from `tx_chunks_receiver` */,
    acks_out_rx: &mut /* `Receiver` for ACKs from `acks_to_wire_receiver` */,
) {
    let _ = secure_serial::run_write(&mut /* uart */, tx_rx, acks_out_rx, &mut /* crc */).await;
}

Implementations§

Source§

impl<M: RawMutex + 'static, const N_INFLIGHT: usize, const N_RX_POOL: usize, const N_BUF: usize> SecureSerialResources<M, N_INFLIGHT, N_RX_POOL, N_BUF>

Source

pub fn new() -> Self

Builds pools and channels; all buffers start empty and channels empty.

§Panics

If N_INFLIGHT or N_RX_POOL is not in 1..=32.

Source

pub fn tx_pool(&self) -> &BufferPool<M, Vec<u8, CHUNK_LEN_MAX>, N_INFLIGHT>

Pool for outbound DATA chunks; pass to crate::SecureSerialSender::new when self is 'static.

Source

pub fn tx_chunks_sender( &self, ) -> Sender<'_, M, BufferGuard<M, Vec<u8, CHUNK_LEN_MAX>>, N_INFLIGHT>

Sender for encoded DATA chunks consumed by crate::run_write.

Source

pub fn tx_chunks_receiver( &self, ) -> Receiver<'_, M, BufferGuard<M, Vec<u8, CHUNK_LEN_MAX>>, N_INFLIGHT>

Receiver used by crate::run_write for pending DATA frames.

Source

pub fn acks_to_wire_sender(&self) -> Sender<'_, M, Ack, N_INFLIGHT>

ACKs generated locally that must be written to the wire (feed crate::run_write).

Source

pub fn acks_to_wire_receiver(&self) -> Receiver<'_, M, Ack, N_INFLIGHT>

Source

pub fn acks_from_peer_sender(&self) -> Sender<'_, M, Ack, N_INFLIGHT>

ACKs received from the peer (feed crate::SecureSerialSender::new as rx_confirm).

Source

pub fn acks_from_peer_receiver(&self) -> Receiver<'_, M, Ack, N_INFLIGHT>

Source

pub fn rx_pool(&self) -> &BufferPool<M, [u8; N_BUF], N_RX_POOL>

Pool for partially reassembled RX packets; pass to crate::run_read when self is 'static.

Source

pub fn rx_complete_sender( &self, ) -> Sender<'_, M, MappedBufferGuard<M, [u8]>, N_RX_POOL>

Completed packets from crate::run_read.

Source

pub fn rx_complete_receiver( &self, ) -> Receiver<'_, M, MappedBufferGuard<M, [u8]>, N_RX_POOL>

Auto Trait Implementations§

§

impl<M, const N_INFLIGHT: usize, const N_RX_POOL: usize, const N_BUF: usize> !Freeze for SecureSerialResources<M, N_INFLIGHT, N_RX_POOL, N_BUF>

§

impl<M, const N_INFLIGHT: usize, const N_RX_POOL: usize, const N_BUF: usize> !RefUnwindSafe for SecureSerialResources<M, N_INFLIGHT, N_RX_POOL, N_BUF>

§

impl<M, const N_INFLIGHT: usize, const N_RX_POOL: usize, const N_BUF: usize> !Send for SecureSerialResources<M, N_INFLIGHT, N_RX_POOL, N_BUF>

§

impl<M, const N_INFLIGHT: usize, const N_RX_POOL: usize, const N_BUF: usize> !Sync for SecureSerialResources<M, N_INFLIGHT, N_RX_POOL, N_BUF>

§

impl<M, const N_INFLIGHT: usize, const N_RX_POOL: usize, const N_BUF: usize> Unpin for SecureSerialResources<M, N_INFLIGHT, N_RX_POOL, N_BUF>
where M: Unpin,

§

impl<M, const N_INFLIGHT: usize, const N_RX_POOL: usize, const N_BUF: usize> UnsafeUnpin for SecureSerialResources<M, N_INFLIGHT, N_RX_POOL, N_BUF>
where M: UnsafeUnpin,

§

impl<M, const N_INFLIGHT: usize, const N_RX_POOL: usize, const N_BUF: usize> !UnwindSafe for SecureSerialResources<M, N_INFLIGHT, N_RX_POOL, N_BUF>

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.