@@ -28,6 +28,7 @@ The time utilities API supports:
28
28
29
29
* :ref: `converting between time representations <timeutil_repr >`
30
30
* :ref: `synchronizing and aligning time scales <timeutil_sync >`
31
+ * :ref: `comparing, adding, and subtracting representations <timeutil_manip >`
31
32
32
33
For terminology and concepts that support these functions see
33
34
:ref: `timeutil_concepts `.
@@ -106,6 +107,88 @@ process:
106
107
107
108
.. doxygengroup :: timeutil_sync_apis
108
109
110
+ .. _timeutil_manip :
111
+
112
+ ``timespec `` Manipulation
113
+ =========================
114
+
115
+ Checking the validity of a ``timespec `` can be done with :c:func: `timespec_is_valid `.
116
+
117
+ .. code-block :: c
118
+
119
+ struct timespec ts = {
120
+ .tv_sec = 0,
121
+ .tv_nsec = -1, /* out of range! */
122
+ };
123
+
124
+ if (!timespec_is_valid(&ts)) {
125
+ /* error-handing code */
126
+ }
127
+
128
+ In some cases, invalid ``timespec `` objects may be re-normalized using
129
+ :c:func: `timespec_normalize `.
130
+
131
+ .. code-block :: c
132
+
133
+ if (timespec_normalize(&ts)) {
134
+ /* this indicates overflow, but is not reachable with the definition of ts above */
135
+ }
136
+
137
+ /* ts should be normalized */
138
+ __ASSERT(timespec_is_valid(&ts) == true, "expected normalized timespec");
139
+
140
+ It is possible to compare two ``timespec `` objects for equality using :c:func: `timespec_equal `.
141
+
142
+ .. code-block :: c
143
+
144
+ if (timespec_equal(then, now)) {
145
+ /* time is up! */
146
+ }
147
+
148
+ It is possible to compare and fully order (valid) ``timespec `` objects using
149
+ :c:func: `timespec_compare `.
150
+
151
+ .. code-block :: c
152
+
153
+ int cmp = timespec_compare(a, b);
154
+
155
+ switch (cmp) {
156
+ case 0:
157
+ /* a == b */
158
+ break;
159
+ case -1:
160
+ /* a < b */
161
+ break;
162
+ case +1:
163
+ /* a > b */
164
+ break;
165
+ }
166
+
167
+ It is possible to add, subtract, and negate ``timespec `` objects using :c:func: `timespec_add `,
168
+ :c:func: `timespec_sub `, and :c:func: `timespec_negate `, respectively. Like
169
+ :c:func: `timespec_normalize `, these functions will output a normalized ``timespec `` when
170
+ doing so would not result in overflow. If overflow would occur, the functions return ``true ``.
171
+
172
+ .. code-block :: c
173
+
174
+ /* a += b */
175
+ if (timespec_add(&a, &b)) {
176
+ /* overflow */
177
+ }
178
+
179
+ /* a -= b */
180
+ if (timespec_sub(&a, &b)) {
181
+ /* overflow */
182
+ }
183
+
184
+ /* a = -a */
185
+ if (timespec_negate(&a)) {
186
+ /* overflow */
187
+ }
188
+
189
+ .. doxygengroup :: timeutil_timespec_apis
190
+
191
+
109
192
.. _timeutil_concepts :
110
193
111
194
Concepts Underlying Time Support in Zephyr
@@ -236,3 +319,29 @@ The mechanism used to populate synchronization points is not relevant: it may
236
319
involve reading from a local high-precision RTC peripheral, exchanging packets
237
320
over a network using a protocol like NTP or PTP, or processing NMEA messages
238
321
received a GPS with or without a 1pps signal.
322
+
323
+ ``timespec `` Concepts
324
+ =====================
325
+
326
+ Originally from POSIX, ``struct timespec `` has been a part of the C standard
327
+ since C11. The definition of ``struct timespec `` is as shown below.
328
+
329
+ .. code-block :: c
330
+
331
+ struct timespec {
332
+ time_t tv_sec; /* seconds */
333
+ long tv_nsec; /* nanoseconds */
334
+ };
335
+
336
+ .. _note :
337
+
338
+ The C standard does not define the size of ``time_t ``. However, Zephyr
339
+ uses 64-bits for ``time_t ``. The ``long `` type is required to be at least
340
+ 32-bits, but usually matches the word size of the architecture. Both
341
+ elements of ``struct timespec `` are signed integers. ``time_t `` is defined
342
+ to be 64-bits both for historical reasons and to be robust enough to
343
+ represent times in the future.
344
+
345
+ The ``tv_nsec `` field is only valid with values in the range ``[0, 999999999] ``. The
346
+ ``tv_sec `` field is the number of seconds since the epoch. If ``struct timespec `` is
347
+ used to express a difference, the ``tv_sec `` field may fall into a negative range.
0 commit comments