@@ -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,90 @@ 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
+ /* error-handling code */
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
168
+ :c:func: `timespec_add `, :c:func: `timespec_sub `, and :c:func: `timespec_negate `,
169
+ respectively. Like :c:func: `timespec_normalize `, these functions will output
170
+ a normalized ``timespec `` when doing so would not result in overflow.
171
+ On success, these functions return ``true ``. If overflow would occur, the
172
+ functions return ``false ``.
173
+
174
+ .. code-block :: c
175
+
176
+ /* a += b */
177
+ if (!timespec_add(&a, &b)) {
178
+ /* overflow */
179
+ }
180
+
181
+ /* a -= b */
182
+ if (!timespec_sub(&a, &b)) {
183
+ /* overflow */
184
+ }
185
+
186
+ /* a = -a */
187
+ if (!timespec_negate(&a)) {
188
+ /* overflow */
189
+ }
190
+
191
+ .. doxygengroup :: timeutil_timespec_apis
192
+
193
+
109
194
.. _timeutil_concepts :
110
195
111
196
Concepts Underlying Time Support in Zephyr
@@ -236,3 +321,29 @@ The mechanism used to populate synchronization points is not relevant: it may
236
321
involve reading from a local high-precision RTC peripheral, exchanging packets
237
322
over a network using a protocol like NTP or PTP, or processing NMEA messages
238
323
received a GPS with or without a 1pps signal.
324
+
325
+ ``timespec `` Concepts
326
+ =====================
327
+
328
+ Originally from POSIX, ``struct timespec `` has been a part of the C standard
329
+ since C11. The definition of ``struct timespec `` is as shown below.
330
+
331
+ .. code-block :: c
332
+
333
+ struct timespec {
334
+ time_t tv_sec; /* seconds */
335
+ long tv_nsec; /* nanoseconds */
336
+ };
337
+
338
+ .. _note :
339
+
340
+ The C standard does not define the size of ``time_t ``. However, Zephyr
341
+ uses 64-bits for ``time_t ``. The ``long `` type is required to be at least
342
+ 32-bits, but usually matches the word size of the architecture. Both
343
+ elements of ``struct timespec `` are signed integers. ``time_t `` is defined
344
+ to be 64-bits both for historical reasons and to be robust enough to
345
+ represent times in the future.
346
+
347
+ The ``tv_nsec `` field is only valid with values in the range ``[0, 999999999] ``. The
348
+ ``tv_sec `` field is the number of seconds since the epoch. If ``struct timespec `` is
349
+ used to express a difference, the ``tv_sec `` field may fall into a negative range.
0 commit comments