Line data Source code
1 1 : /*
2 : * Copyright (c) 2018 Intel Corporation.
3 : *
4 : * SPDX-License-Identifier: Apache-2.0
5 : */
6 :
7 : /**
8 : * @file
9 : * @brief Public functions for the Precision Time Protocol time specification.
10 : *
11 : * References are to version 2019 of IEEE 1588, ("PTP")
12 : * and version 2020 of IEEE 802.1AS ("gPTP").
13 : */
14 :
15 : #ifndef ZEPHYR_INCLUDE_NET_PTP_TIME_H_
16 : #define ZEPHYR_INCLUDE_NET_PTP_TIME_H_
17 :
18 : /**
19 : * @brief Precision Time Protocol time specification
20 : * @defgroup ptp_time PTP time
21 : * @since 1.13
22 : * @version 0.8.0
23 : * @ingroup networking
24 : * @{
25 : */
26 :
27 : #include <zephyr/net/net_core.h>
28 : #include <zephyr/net/net_time.h>
29 : #include <zephyr/toolchain.h>
30 :
31 : #ifdef __cplusplus
32 : extern "C" {
33 : #endif
34 :
35 : /**
36 : * @brief (Generalized) Precision Time Protocol Timestamp format.
37 : *
38 : * @details This structure represents a timestamp according to the Precision
39 : * Time Protocol standard ("PTP", IEEE 1588, section 5.3.3), the Generalized
40 : * Precision Time Protocol standard ("gPTP", IEEE 802.1AS, section 6.4.3.4), or
41 : * any other well-defined context in which precision structured timestamps are
42 : * required on network messages in Zephyr.
43 : *
44 : * Seconds are encoded as a 48 bits unsigned integer. Nanoseconds are encoded
45 : * as a 32 bits unsigned integer.
46 : *
47 : * In the context of (g)PTP, @em timestamps designate the time, relative to a
48 : * local clock ("LocalClock") at which the message timestamp point passes a
49 : * reference plane marking the boundary between the PTP Instance and the network
50 : * medium (IEEE 1855, section 7.3.4.2; IEEE 802.1AS, section 8.4.3).
51 : *
52 : * The exact definitions of the <em>message timestamp point</em> and
53 : * <em>reference plane</em> depends on the network medium and use case.
54 : *
55 : * For (g)PTP the media-specific message timestamp points and reference planes
56 : * are defined in the standard. In non-PTP contexts specific to Zephyr,
57 : * timestamps are measured relative to the same local clock but with a
58 : * context-specific message timestamp point and reference plane, defined below
59 : * per use case.
60 : *
61 : * A @em "LocalClock" is a freerunning clock, embedded into a well-defined
62 : * entity (e.g. a PTP Instance) and provides a common time to that entity
63 : * relative to an arbitrary epoch (IEEE 1855, section 3.1.26, IEEE 802.1AS,
64 : * section 3.16).
65 : *
66 : * In Zephyr, the local clock is usually any instance of a kernel system clock
67 : * driver, counter driver, RTC API driver or low-level counter/timer peripheral
68 : * (e.g. an ethernet peripheral with hardware timestamp support or a radio
69 : * timer) with sufficient precision for the context in which it is used.
70 : *
71 : * See IEEE 802.1AS, Annex B for specific performance requirements regarding
72 : * conformance of local clocks in the gPTP context. See IEEE 1588, Annex A,
73 : * section A5.4 for general performance requirements regarding PTP local clocks.
74 : * See IEEE 802.15.4-2020, section 15.7 for requirements in the context of
75 : * ranging applications and ibid., section 6.7.6 for the relation between guard
76 : * times and clock accuracy which again influence the precision required for
77 : * subprotocols like CSL, TSCH, RIT, etc.
78 : *
79 : * Applications that use timestamps across different subsystems or media must
80 : * ensure that they understand the definition of the respective reference planes
81 : * and interpret timestamps accordingly. Applications must further ensure that
82 : * timestamps are either all referenced to the same local clock or convert
83 : * between clocks based on sufficiently precise conversion algorithms.
84 : *
85 : * Timestamps may be measured on ingress (RX timestamps) or egress (TX
86 : * timestamps) of network messages. Timestamps can also be used to schedule a
87 : * network message to a well-defined point in time in the future at which it is
88 : * to be sent over the medium (timed TX). A future timestamp and a duration,
89 : * both referenced to the local clock, may be given to specify a time window at
90 : * which a network device should expect incoming messages (RX window).
91 : *
92 : * In Zephyr this timestamp structure is currently used in the following
93 : * contexts:
94 : * * gPTP for Full Duplex Point-to-Point IEEE 802.3 links (IEEE 802.1AS,
95 : * section 11): the reference plane and message timestamp points are as
96 : * defined in the standard.
97 : * * IEEE 802.15.4 timed TX and RX: Timestamps designate the point in time at
98 : * which the end of the last symbol of the start-of-frame delimiter (SFD) (or
99 : * equivalently, the start of the first symbol of the PHY header) is at the
100 : * local antenna. The standard also refers to this as the "RMARKER" (IEEE
101 : * 802.15.4-2020, section 6.9.1) or "symbol boundary" (ibid., section 6.5.2),
102 : * depending on the context. In the context of beacon timestamps, the
103 : * difference between the timestamp measurement plane and the reference plane
104 : * is defined by the MAC PIB attribute "macSyncSymbolOffset", ibid., section
105 : * 8.4.3.1, table 8-94.
106 : *
107 : * If further use cases are added to Zephyr using this timestamp structure,
108 : * their clock performance requirements, message timestamp points and reference
109 : * plane definition SHALL be added to the above list.
110 : */
111 1 : struct net_ptp_time {
112 : /** Seconds encoded on 48 bits. */
113 : union {
114 :
115 : /** @cond INTERNAL_HIDDEN */
116 : struct {
117 : #ifdef CONFIG_LITTLE_ENDIAN
118 : uint32_t low;
119 : uint16_t high;
120 : uint16_t unused;
121 : #else
122 : uint16_t unused;
123 : uint16_t high;
124 : uint32_t low;
125 : #endif
126 : } _sec;
127 : /** @endcond */
128 :
129 : /** Second value. */
130 1 : uint64_t second;
131 1 : };
132 :
133 : /** Nanoseconds. */
134 1 : uint32_t nanosecond;
135 : };
136 :
137 : #ifdef __cplusplus
138 : }
139 : #endif
140 :
141 : /**
142 : * @brief Generalized Precision Time Protocol Extended Timestamp format.
143 : *
144 : * @details This structure represents an extended timestamp according to the
145 : * Generalized Precision Time Protocol standard (IEEE 802.1AS), see section
146 : * 6.4.3.5.
147 : *
148 : * Seconds are encoded as 48 bits unsigned integer. Fractional nanoseconds are
149 : * encoded as 48 bits, their unit is 2*(-16) ns.
150 : *
151 : * A precise definition of PTP timestamps and their uses in Zephyr is given in
152 : * the description of @ref net_ptp_time.
153 : */
154 1 : struct net_ptp_extended_time {
155 : /** Seconds encoded on 48 bits. */
156 : union {
157 :
158 : /** @cond INTERNAL_HIDDEN */
159 : struct {
160 : #ifdef CONFIG_LITTLE_ENDIAN
161 : uint32_t low;
162 : uint16_t high;
163 : uint16_t unused;
164 : #else
165 : uint16_t unused;
166 : uint16_t high;
167 : uint32_t low;
168 : #endif
169 : } _sec;
170 : /** @endcond */
171 :
172 : /** Second value. */
173 1 : uint64_t second;
174 1 : };
175 :
176 : /** Fractional nanoseconds on 48 bits. */
177 : union {
178 :
179 : /** @cond INTERNAL_HIDDEN */
180 : struct {
181 : #ifdef CONFIG_LITTLE_ENDIAN
182 : uint32_t low;
183 : uint16_t high;
184 : uint16_t unused;
185 : #else
186 : uint16_t unused;
187 : uint16_t high;
188 : uint32_t low;
189 : #endif
190 : } _fns;
191 : /** @endcond */
192 :
193 : /** Fractional nanoseconds value. */
194 1 : uint64_t fract_nsecond;
195 1 : };
196 : } __packed;
197 :
198 : /**
199 : * @brief Convert a PTP timestamp to a nanosecond precision timestamp, both
200 : * related to the local network reference clock.
201 : *
202 : * @note Only timestamps representing up to ~290 years can be converted to
203 : * nanosecond timestamps. Larger timestamps will return the maximum
204 : * representable nanosecond precision timestamp.
205 : *
206 : * @param ts the PTP timestamp
207 : *
208 : * @return the corresponding nanosecond precision timestamp
209 : */
210 1 : static inline net_time_t net_ptp_time_to_ns(struct net_ptp_time *ts)
211 : {
212 : if (!ts) {
213 : return 0;
214 : }
215 :
216 : if (ts->second >= NET_TIME_SEC_MAX) {
217 : return NET_TIME_MAX;
218 : }
219 :
220 : return ((int64_t)ts->second * NSEC_PER_SEC) + ts->nanosecond;
221 : }
222 :
223 : /**
224 : * @brief Convert a nanosecond precision timestamp to a PTP timestamp, both
225 : * related to the local network reference clock.
226 : *
227 : * @param nsec a nanosecond precision timestamp
228 : *
229 : * @return the corresponding PTP timestamp
230 : */
231 1 : static inline struct net_ptp_time ns_to_net_ptp_time(net_time_t nsec)
232 : {
233 : struct net_ptp_time ts;
234 :
235 : __ASSERT_NO_MSG(nsec >= 0);
236 :
237 : ts.second = nsec / NSEC_PER_SEC;
238 : ts.nanosecond = nsec % NSEC_PER_SEC;
239 : return ts;
240 : }
241 :
242 : /**
243 : * @}
244 : */
245 :
246 : #endif /* ZEPHYR_INCLUDE_NET_PTP_TIME_H_ */
|