1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// Copyright 2026 Ethan Wu
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0
//! Core inter-processor communication primitives for Consortium.
//!
//! This crate is the abstraction layer that every Consortium link is built from.
//! It defines the trait stack, the typed endpoints application and firmware code
//! call, and the marker types that keep a message meaningful on both sides of a
//! core boundary. It performs no hardware access, no allocation, and hosts no
//! executor; concrete links live in `consortium-ipc-transport-*`, concrete
//! signaling in `consortium-ipc-doorbell-*`, and serialization in
//! `consortium-codec`.
//!
//! # Architecture
//!
//! Five traits compose into two user-facing types:
//!
//! ```text
//! 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 channel
//! ```
//!
//! - [`Doorbell`] is pure signaling. Its ordering contract — writes before `ring`
//! happen-before the peer's `wait` — is what makes shared-memory
//! payloads safe to read on the far side.
//! - [`SendTransport`] and [`RecvTransport`] move bytes and report their MTU. Both
//! return `impl Future<..> + MaybeSend`, so implementations may be plain
//! `async fn`s awaiting unnameable futures.
//! - [`Channel`] adds a message type and a [`consortium_codec::CodecFor`] to one
//! transport half.
//! It never allocates: the caller supplies a `&'static mut [u8]` scratch buffer
//! sized for the transport MTU.
//! - [`Transceiver`] pairs a [`Tx`] and an [`Rx`] channel, 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
//!
//! ```rust,ignore
//! 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`](Channel::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`].
//! 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` — link `alloc`.
//! - `futures` — futures-oriented helpers.
//! - `tracing` — route internal logging to `consortium-log`'s `tracing` backend.
//! - `defmt` — route internal logging to `defmt` and derive `defmt::Format`.
//! - `std` — `alloc + futures + tracing`, and makes [`MaybeSend`] require `Send`
//! (which Tokio's multi-threaded executor needs). Leave it off for Embassy.
extern crate alloc;
pub
pub
pub
pub
pub
pub
pub
pub
pub
pub
pub
pub use ;
pub use IpcSafe;