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
//! # Emcyphal
//!
//! This library provides an async socket-like API for the Cyphal/CAN protocol \[1\] in no_std
//! environments. It uses user-provided buffers for (de)segmentation and queues, requiring no
//! dynamic memory allocation.
//!
//! The library is designed for systems with tight interrupt latency requirements, keeping all
//! critical section durations bounded.
//!
//! The library primarily targets the Embassy async framework, though tokio/SocketCAN extensions
//! may be possible in the future.
//!
//! ## Architecture
//!
//! ```text
//! ┌────────┐
//! │ Runner │
//! └────┬───┘
//! ▼
//! ┌──────┐ ┌────────┐ ┌─────┐
//! │ Link ├─►│ Node │◄─┤ Hub │
//! └──────┘ └──────┬─┘ └──┬──┘
//! │ │ ┌───────────────────┐
//! │ │ │ Subscriber socket │
//! ┌─────────────┐ │ │ │ ┌───────────────┐ │
//! │ RX Buffer 1 │◄─┤ │◄─┼─┤ RX Endpoint 1 │ │
//! └─────────────┘ │ │ │ └───────────────┘ │
//! │ │ └───────────────────┘
//! │ │ ┌───────────────────┐
//! │ │ │ Publisher socket │
//! ┌─────────────┐ │ │ │ ┌───────────────┐ │
//! │ TX Buffer 1 │◄─┤ │◄─┼─┤ TX Endpoint 1 │ │
//! └─────────────┘ │ │ │ └───────────────┘ │
//! │ │ └───────────────────┘
//! │ │ ┌───────────────────┐
//! │ │ │ Responder socket │
//! ┌─────────────┐ │ │ │ ┌───────────────┐ │
//! │ RX Buffer 2 │◄─┤ │◄─┼─┤ RX Endpoint 2 │ │
//! └─────────────┘ │ │ │ └───────────────┘ │
//! ┌─────────────┐ │ │ │ ┌───────────────┐ │
//! │ TX Buffer 2 │◄─┤ │◄─┼─┤ TX Endpoint 2 │ │
//! └─────────────┘ │ │ │ └───────────────┘ │
//! └───────────────────┘
//! ...
//! ```
//! Components:
//! * _Node_ holds Cyphal peer data (e.g., NodeId, Health, Mode) and type-agnostic links to
//! registered buffers. It distributes incoming frames among RX buffers and collects outgoing
//! frames from TX buffers. It also proxies and synchronizes endpoint access to the associated
//! buffers.
//! * _Runner_ is a worker task for background node activities, e.g., publishing heartbeats and port lists,
//! and answering GetInfo, GetTransportStatistics service requests.
//! * _Link_ is an asynchronous channel for CAN frames that a CAN peripheral driver consumes.
//! * _Hub_ is a shared handle for creating new endpoints.
//! * _Buffer_ is a type-aware object that manages (de)segmentation and a transfer queue.
//! * _Endpoint_ is a low-level API handle for sending or receiving transfers.
//! It performs (de)serialization and guards the buffer's lifetime.
//! * _Socket_ is a higher-level API handle for networking. Users are encouraged to use sockets
//! instead of endpoints when possible.
//!
//! Upon creation, an endpoint registers the associated buffer reference with the Hub.
//! The reference lifetime is bounded by the endpoint. Once dropped, it unregisters the buffer
//! immediately. This allows users to use temporarily allocated buffers within async function scopes.
//!
//! Network-capable objects are expected to consume sockets, allowing users to compose independent
//! components within a single Cyphal node.
//!
//! ## Concurrency model
//!
//! The Node owns unique references to the registered buffers and uses a mutex to synchronize
//! Driver, Runner, and endpoint accesses. There are two mutex implementation options:
//! * _CriticalSectionRawMutex_ allows stack components to run concurrently (at different
//! interrupt levels), but can add bounded priority inversion (interrupt latency) to the
//! rest of the system.
//! * _ThreadModeRawMutex_ has no system-wide effects but requires all stack components to run
//! in a thread (non-interrupt) executor. Priority inversion is possible among endpoints,
//! and long processing delays may affect the Driver.
//!
//! The library keeps critical section durations bounded to O(log(N)) CPU cycles, where N is the
//! number of endpoints of the given type. For example:
//! * The Node maintains the buffer index in a tree-like structure for deterministic worst-case complexity.
//! * Delivery of an incoming frame to each subscribed buffer runs in a dedicated critical section.
//! * (De)serialization runs in the caller's thread, outside the critical section.
//! The mutex is held briefly for a zero-copy buffer swap.
//!
//! ## Cyphal data types
//!
//! The library relies on a modified code generator from the `canadensis` project to convert Cyphal
//! DSDL to (de)serializable Rust structs. The modified version annotates each data type with an
//! auxiliary buffer type that can hold the longest type serialization.
//!
//! ## Limitations
//!
//! * Service requests are not yet implemented.
//! * Loop-back transfers are supported for messages only.
//! * The no_std target supports single-CPU systems only (embassy_sync limitation).
//! * Redundant transports are not supported.
//! * Anonymous message publication is not supported.
//!
//! # References:
//!
//! * \[1\] Cyphal Specification v1.0
//! <https://opencyphal.org/specification/Cyphal_Specification.pdf>
pub use emcyphal_core as core;
pub use ;
// This mod MUST go first, so that the others see its macros.
pub