Skip to content

Commit 01b9a9b

Browse files
Update the docs for Cyphal/UDP and Cyphal/serial (#301)
This is a trivial update to the docs to remove duplication with the official Specification.
1 parent de11875 commit 01b9a9b

File tree

9 files changed

+27
-358
lines changed

9 files changed

+27
-358
lines changed

pycyphal/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "1.15.1"
1+
__version__ = "1.15.2"

pycyphal/application/_transport_factory.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def make_transport(
5252
5353
* - ``uavcan.udp.duplicate_service_transfers``
5454
- ``bit[1]``
55-
- Apply deterministic data loss mitigation to RPC-service transfers by setting multiplication factor = 2.
55+
- Apply forward error correction to RPC-service transfers by setting multiplication factor = 2.
5656
5757
* - ``uavcan.udp.mtu``
5858
- ``natural16[1]``
@@ -73,7 +73,7 @@ def make_transport(
7373
7474
* - ``uavcan.serial.duplicate_service_transfers``
7575
- ``bit[1]``
76-
- Apply deterministic data loss mitigation to RPC-service transfers by setting multiplication factor = 2.
76+
- Apply forward error correction to RPC-service transfers by setting multiplication factor = 2.
7777
7878
* - ``uavcan.serial.baudrate``
7979
- ``natural32[1]``

pycyphal/transport/_transport.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ def begin_capture(self, handler: CaptureCallback) -> None:
207207
Technically, the capture protocol, as you can see, does not present any requirements to the emitted events,
208208
so an implementation that pretends to enter the capture mode while not actually doing anything is compliant.
209209
210-
Since capture reflects actual network events, deterministic data loss mitigation will make the instance emit
210+
Since capture reflects actual network events, FEC will make the instance emit
211211
duplicate frames for affected transfers (although this is probably obvious enough without this elaboration).
212212
213213
It is not possible to disable capture. Once enabled, it will go on until the transport instance is destroyed.

pycyphal/transport/redundant/_tracer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def get_transport_type() -> typing.Type[pycyphal.transport.redundant.RedundantTr
4747
class RedundantDuplicateTransferTrace(pycyphal.transport.Trace):
4848
"""
4949
Indicates that the last capture object completed a valid transfer that was discarded as a duplicate
50-
(either received from another redundant interface or deterministic data loss mitigation (DDLM) is employed).
50+
(either received from another redundant interface or forward error correction is employed).
5151
5252
Observe that it is NOT a subclass of :class:`pycyphal.transport.TransferTrace`!
5353
It shall not be one because duplicates should not be processed normally.

pycyphal/transport/serial/__init__.py

Lines changed: 10 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -3,118 +3,28 @@
33
# Author: Pavel Kirienko <pavel@opencyphal.org>
44

55
"""
6-
Cyphal/Serial transport overview
6+
Cyphal/serial transport overview
77
++++++++++++++++++++++++++++++++
88
9-
The Cyphal/Serial transport is designed for OSI L1 byte-level duplex serial links and tunnels:
9+
The Cyphal/serial transport is designed for byte-level communication channels, such as:
1010
11-
- UART, RS-422/485/232 (duplex); the recommended rates are: 115200 bps, 921600 bps, 3 Mbps, 10 Mbps, 100 Mbps.
12-
- USB CDC ACM.
13-
- TCP/IP encapsulation.
11+
- TCP/IP
12+
- UART, RS-422/232
13+
- USB CDC ACM
1414
15-
It may also be suited for raw transport log storage, because one-dimensional flat binary files are structurally
16-
similar to serial byte-level links.
15+
It may also be suited for raw transport log storage.
1716
1817
This transport module contains no media sublayers because the media abstraction
1918
is handled directly by the `PySerial <https://pypi.org/project/pyserial>`_
2019
library and the underlying operating system.
2120
22-
The serial transport supports all transfer categories:
21+
For the full protocol definition, please refer to the `Cyphal Specification <https://opencyphal.org/specification>`_.
2322
24-
+--------------------+--------------------------+---------------------------+
25-
| Supported transfers| Unicast | Broadcast |
26-
+====================+==========================+===========================+
27-
|**Message** | Yes, non-spec extension | Yes |
28-
+--------------------+--------------------------+---------------------------+
29-
|**Service** | Yes | Banned by Specification |
30-
+--------------------+--------------------------+---------------------------+
3123
24+
Forward error correction (FEC)
25+
++++++++++++++++++++++++++++++
3226
33-
Protocol definition
34-
+++++++++++++++++++
35-
36-
The packet header is defined as follows (byte/bit ordering in this definition follow the DSDL specification:
37-
least significant first)::
38-
39-
uint4 version # = 1, Discard the frame if not.
40-
void4
41-
42-
uint3 priority # 0 = highest, 7 = lowest; the rest are unused.
43-
void5
44-
45-
uint16 source_node_id # 0xFFFF = anonymous.
46-
uint16 destination_node_id # 0xFFFF = broadcast.
47-
uint16 data_specifier # subject-ID | (service-ID + RNR (Request, Not Response))
48-
49-
uint64 transfer_id
50-
51-
uint31 frame_index
52-
bool end_of_transfer # Set if last frame of the transfer
53-
54-
uint16 user_data # Opaque application-specific data with user-defined semantics.
55-
# Generic implementations should ignore
56-
57-
uint8[2] header_crc_be # CRC-16-CCITT of the header (all fields above).
58-
# Most significant byte first.
59-
60-
For message frames, the data specifier field contains the subject-ID value,
61-
so that the most significant bit is always cleared.
62-
For service frames, the most significant bit (15th) is always set,
63-
and the second-to-most-significant bit (14th) is set for request transfers only;
64-
the remaining 14 least significant bits contain the service-ID value.
65-
66-
Total header size: 24 bytes (192 bits).
67-
68-
The header is prepended before the frame payload; the resulting structure is
69-
encoded into its serialized form using the following packet format:
70-
71-
+-------------------------+--------------+---------------+--------------------------------+-------------------------+
72-
| Frame delimiter **0x00**|Escaped header|Escaped payload| Escaped CRC-32C of the payload | Frame delimiter **0x00**|
73-
+=========================+==============+===============+================================+=========================+
74-
| 1 byte | 24 bytes | >=0 bytes | 4 bytes | 1 byte |
75-
+-------------------------+--------------+---------------+--------------------------------+-------------------------+
76-
| Single-byte frame | | Four bytes long, little-endian | Same frame delimiter as |
77-
| delimiter **0x00**. | | byte order; The CRC is | at the start. |
78-
| Begins a new frame and | | computed over the unescaped | Terminates the current |
79-
| possibly terminates the | | (i.e., original form) payload, | frame and possibly |
80-
| previous frame. | | not including the header | begins the next frame. |
81-
| | | (because the header has a | |
82-
| | | dedicated CRC). | |
83-
| +------------------------------+--------------------------------+ |
84-
| | This part is escaped using COBS alorithm by Chesire and Baker | |
85-
| | http://www.stuartcheshire.org/papers/COBSforToN.pdf. | |
86-
| | A frame delimiter (0) is guaranteed to never occur here. | |
87-
+-------------------------+------------------------------+--------------------------------+-------------------------+
88-
89-
The frame encoding overhead is 1 byte in every 254 bytes of the header+payload+CRC, which is about ~0.4%.
90-
There is a somewhat relevant discussion at
91-
https://forum.opencyphal.org/t/uavcan-serial-issues-with-dma-friendliness-and-bandwidth-overhead/846.
92-
93-
The last four bytes of a multi-frame transfer payload contain the CRC32C (Castagnoli) hash of the transfer
94-
payload in little-endian byte order.
95-
The multi-frame transfer logic (decomposition and reassembly) is implemented in a separate
96-
transport-agnostic module :mod:`pycyphal.transport.commons.high_overhead_transport`.
97-
**Despite the fact that the support for multi-frame transfers is built into this transport,
98-
it should not be relied on and it may be removed later.**
99-
The reason is that serial links do not have native support for framing, and as such,
100-
it is possible to configure the MTU to be arbitrarily high to avoid multi-frame transfers completely.
101-
The lack of multi-frame transfers simplifies implementations drastically, which is important for
102-
deeply-embedded systems. As such, all serial transfers should be single-frame transfers.
103-
104-
Note that we use CRC-32C (Castagnoli) as the header/frame CRC instead of CRC-32K2 (Koopman-2)
105-
which is superior at short data blocks offering the Hamming distance of 6 as opposed to 4.
106-
This is because Castagnoli is superior for transfer CRC which is often sufficiently long
107-
to flip the balance in favor of Castagnoli rather than Koopman.
108-
We could use Koopman for the header/frame CRC and keep Castagnoli for the transfer CRC,
109-
but such diversity is harmful because it would require implementers to keep two separate CRC tables
110-
which may be costly in embedded applications and may deteriorate the performance of CPU caches.
111-
112-
113-
Unreliable links and temporal redundancy
114-
++++++++++++++++++++++++++++++++++++++++
115-
116-
The serial transport supports the deterministic data loss mitigation option,
117-
where a transfer can be repeated several times to reduce the probability of its loss.
27+
This transport supports optional FEC through full duplication of transfers.
11828
This feature is discussed in detail in the documentation for the UDP transport :mod:`pycyphal.transport.udp`.
11929
12030

pycyphal/transport/serial/_serial.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ def __init__(
9999
This setting does not affect transfer reception -- the RX MTU is always set to the maximum valid MTU
100100
(i.e., practically unlimited).
101101
102-
:param service_transfer_multiplier: Deterministic data loss mitigation for service transfers.
102+
:param service_transfer_multiplier: Forward error correction for service transfers.
103103
This parameter specifies the number of times each outgoing service transfer will be repeated.
104104
This setting does not affect message transfers.
105105

0 commit comments

Comments
 (0)