Expand description
Core inter-processor communication primitives for Consortium.
This crate is the abstraction layer that every Consortium link is built from.
It defines the typed endpoints application and firmware code call and the
marker types that keep a message meaningful on both sides of a core boundary,
and re-exports the transport and doorbell traits beneath them. It performs no
hardware access, no allocation, and hosts no executor; concrete links live in
consortium-ipc-transport-*, serialization in consortium-codec, and the
transport and doorbell traits themselves in consortium-core — below IPC, so
that SCMI and the debug ring share them.
§Architecture
Five traits (the first three defined in consortium-core and re-exported here)
compose into two user-facing types:
Doorbell wake the remote processor (no data)
SendTransport / RecvTransport byte halves; ring or await the doorbell
Connect one-shot readiness rendezvous with the peer
CodecFor<T> serialization family for a message type
Channel<D, T, Tr, C> typed endpoint over one transport half
Transceiver<..> typed endpoint pairing a Tx and an Rx channelDoorbellis pure signaling. Its ordering contract — writes beforeringhappen-before the peer’swait— is what makes shared-memory payloads safe to read on the far side.SendTransportandRecvTransportmove bytes and report their MTU. Both returnimpl Future<..> + MaybeSend, so implementations may be plainasync fns awaiting unnameable futures.Channeladds a message type and aconsortium_codec::CodecForto one transport half. It never allocates: the caller supplies a&'static mut [u8]scratch buffer sized for the transport MTU.Transceiverpairs aTxand anRxchannel, each over its own transport half, into one bidirectional endpoint.
Supporting types: Chan (validated channel id, with per-platform
ChanValidate), Side (Primary / Secondary / Tertiary, the
register view of a multi-ported peripheral), IpcSafe (ABI-portable message
types), and MaybeSend (Send under std, vacuous under no_std).
§Example
use consortium_codec::PostcardCodec;
use consortium_ipc::{Chan, Channel, Connect, Rx, Transceiver, Tx};
// Rendezvous once, before any traffic and before splitting.
transport.connect(params).await?;
let (tx_half, rx_half) = transport.split();
let tx = Channel::<Tx, Command, _, PostcardCodec>::new(chan, tx_half, tx_buf);
let rx = Channel::<Rx, Telemetry, _, PostcardCodec>::new(chan, rx_half, rx_buf);
let mut link = Transceiver::new(tx, rx);
link.send(&Command::Start).await?;
let reply = link.recv().await?;recv yields a ReceivedMessage rather than a bare T, so
owned codecs (Decoded<'buf> = T) and future zero-copy codecs
(Decoded<'buf> = &'buf T::Archived) share one call-site shape.
§Implementing a transport
Implement TransportError to name the error type, then SendTransport
and/or RecvTransport. A transport that hands a frame over in one
non-waiting step (a shared-memory slot) should also implement
TrySendTransport / TryRecvTransport, and can then build its async
halves on consortium_core::wait::park_until.
Implement Connect when a peer must agree before traffic flows, using
Params = () if nothing is negotiated. Report honest max_send_size /
max_recv_size: callers size their scratch buffers from them. If the link owns
a channel-id namespace, implement ChanValidate for a platform marker so
Chan::new::<P>(id) rejects out-of-range ids.
§Features
The crate is no_std unless std is enabled.
alloc— linkalloc.futures— futures-oriented helpers.tracing— route internal logging toconsortium-log’stracingbackend.defmt— route internal logging todefmtand derivedefmt::Format.std—alloc + futures + tracing, and makesMaybeSendrequireSend(which Tokio’s multi-threaded executor needs). Leave it off for Embassy.
Structs§
- Chan
- Channel
- A typed, directed communication endpoint over a transport half.
- Primary
- The first processor side.
- Received
Message - A handle to a decoded received message.
- Rx
- Marker: this channel can only receive.
- Secondary
- The second processor side.
- Tertiary
- The third processor side, for peripherals that connect three processors.
- Transceiver
- A typed, multidirectional endpoint pairing a send half and a receive half.
- Tx
- Marker: this channel can only send.
Enums§
- Channel
Error - Unified error for
Channeloperations. - TryError
- Why a
TrySendTransport::try_sendorTryRecvTransport::try_recvdid not complete.
Traits§
- AckSend
Transport - A
SendTransportthat can also wait for the peer to take the message. - Chan
Validate - Platform-specific validation
- Connect
- A transport that must rendezvous with its remote peer before carrying traffic.
- Direction
- Channel direction marker (
TxorRx). - Doorbell
- Notifies the remote core that something has happened. Carries no data - pure signaling primitive.
- IpcSafe
- Marker trait for types that are safe to transmit as cross-core IPC messages.
- Maybe
Send - Recv
Transport - Receive half of a transport — awaits bytes from the remote side.
- Send
Transport - Send half of a transport — moves bytes to the remote side.
- Side
- A processor-side marker selecting which register view a doorbell drives.
- Transport
Error - Provides the
Errorassociated type shared by every transport trait. - TryRecv
Transport - Receive half of a transport whose take never waits.
- TrySend
Transport - Send half of a transport whose hand-off never waits.
Derive Macros§
- IpcSafe
- Derive macro that validates a struct/enum is safe to use as a cross-core IPC message.