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
// 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
//!
//! Six traits compose into two user-facing types:
//!
//! ```text
//! Doorbell wake the remote processor (no data)
//! SendTransport / RecvTransport byte halves; ring or await the doorbell
//! Transport marker for full-duplex links
//! 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`/`pending` — 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`], plus [`Transport`] as a marker for full-duplex links.
//! 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 use ;
pub use IpcSafe;