doc: kernel: timeutil: add documentation for timespec apis
Add documentation in the timeutil group for recently added functions for validating, comparing, and manipulating `struct timespec` objects as well as functions for converting between representation of time durations as either `struct timespec` or `k_timeout_t`. Signed-off-by: Chris Friedt <cfriedt@tenstorrent.com>
This commit is contained in:
parent
13fe95b51d
commit
03099f30da
@ -28,6 +28,7 @@ The time utilities API supports:
|
||||
|
||||
* :ref:`converting between time representations <timeutil_repr>`
|
||||
* :ref:`synchronizing and aligning time scales <timeutil_sync>`
|
||||
* :ref:`comparing, adding, and subtracting representations <timeutil_manip>`
|
||||
|
||||
For terminology and concepts that support these functions see
|
||||
:ref:`timeutil_concepts`.
|
||||
@ -65,6 +66,20 @@ The inverse transformation is not standardized: APIs like ``mktime()`` expect
|
||||
information about time zones. Zephyr provides this transformation with
|
||||
:c:func:`timeutil_timegm` and :c:func:`timeutil_timegm64`.
|
||||
|
||||
To convert between ``struct timespec`` and ``k_timeout_t`` durations,
|
||||
use :c:func:`timespec_to_timeout` and :c:func:`timespec_from_timeout`.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
k_timeout_t to;
|
||||
struct timespec ts;
|
||||
|
||||
timespec_from_timeout(K_FOREVER, &ts);
|
||||
to = timespec_to_timeout(&ts); /* to == K_FOREVER */
|
||||
|
||||
timespec_from_timeout(K_MSEC(100), &ts);
|
||||
to = timespec_to_timeout(&ts); /* to == K_MSEC(100) */
|
||||
|
||||
.. doxygengroup:: timeutil_repr_apis
|
||||
|
||||
.. _timeutil_sync:
|
||||
@ -106,6 +121,90 @@ process:
|
||||
|
||||
.. doxygengroup:: timeutil_sync_apis
|
||||
|
||||
.. _timeutil_manip:
|
||||
|
||||
``timespec`` Manipulation
|
||||
=========================
|
||||
|
||||
Checking the validity of a ``timespec`` can be done with :c:func:`timespec_is_valid`.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
struct timespec ts = {
|
||||
.tv_sec = 0,
|
||||
.tv_nsec = -1, /* out of range! */
|
||||
};
|
||||
|
||||
if (!timespec_is_valid(&ts)) {
|
||||
/* error-handing code */
|
||||
}
|
||||
|
||||
In some cases, invalid ``timespec`` objects may be re-normalized using
|
||||
:c:func:`timespec_normalize`.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
if (!timespec_normalize(&ts)) {
|
||||
/* error-handling code */
|
||||
}
|
||||
|
||||
/* ts should be normalized */
|
||||
__ASSERT(timespec_is_valid(&ts) == true, "expected normalized timespec");
|
||||
|
||||
It is possible to compare two ``timespec`` objects for equality using :c:func:`timespec_equal`.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
if (timespec_equal(then, now)) {
|
||||
/* time is up! */
|
||||
}
|
||||
|
||||
It is possible to compare and fully order (valid) ``timespec`` objects using
|
||||
:c:func:`timespec_compare`.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
int cmp = timespec_compare(a, b);
|
||||
|
||||
switch (cmp) {
|
||||
case 0:
|
||||
/* a == b */
|
||||
break;
|
||||
case -1:
|
||||
/* a < b */
|
||||
break;
|
||||
case +1:
|
||||
/* a > b */
|
||||
break;
|
||||
}
|
||||
|
||||
It is possible to add, subtract, and negate ``timespec`` objects using
|
||||
:c:func:`timespec_add`, :c:func:`timespec_sub`, and :c:func:`timespec_negate`,
|
||||
respectively. Like :c:func:`timespec_normalize`, these functions will output
|
||||
a normalized ``timespec`` when doing so would not result in overflow.
|
||||
On success, these functions return ``true``. If overflow would occur, the
|
||||
functions return ``false``.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
/* a += b */
|
||||
if (!timespec_add(&a, &b)) {
|
||||
/* overflow */
|
||||
}
|
||||
|
||||
/* a -= b */
|
||||
if (!timespec_sub(&a, &b)) {
|
||||
/* overflow */
|
||||
}
|
||||
|
||||
/* a = -a */
|
||||
if (!timespec_negate(&a)) {
|
||||
/* overflow */
|
||||
}
|
||||
|
||||
.. doxygengroup:: timeutil_timespec_apis
|
||||
|
||||
|
||||
.. _timeutil_concepts:
|
||||
|
||||
Concepts Underlying Time Support in Zephyr
|
||||
@ -236,3 +335,29 @@ The mechanism used to populate synchronization points is not relevant: it may
|
||||
involve reading from a local high-precision RTC peripheral, exchanging packets
|
||||
over a network using a protocol like NTP or PTP, or processing NMEA messages
|
||||
received a GPS with or without a 1pps signal.
|
||||
|
||||
``timespec`` Concepts
|
||||
=====================
|
||||
|
||||
Originally from POSIX, ``struct timespec`` has been a part of the C standard
|
||||
since C11. The definition of ``struct timespec`` is as shown below.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
struct timespec {
|
||||
time_t tv_sec; /* seconds */
|
||||
long tv_nsec; /* nanoseconds */
|
||||
};
|
||||
|
||||
.. _note:
|
||||
|
||||
The C standard does not define the size of ``time_t``. However, Zephyr
|
||||
uses 64-bits for ``time_t``. The ``long`` type is required to be at least
|
||||
32-bits, but usually matches the word size of the architecture. Both
|
||||
elements of ``struct timespec`` are signed integers. ``time_t`` is defined
|
||||
to be 64-bits both for historical reasons and to be robust enough to
|
||||
represent times in the future.
|
||||
|
||||
The ``tv_nsec`` field is only valid with values in the range ``[0, 999999999]``. The
|
||||
``tv_sec`` field is the number of seconds since the epoch. If ``struct timespec`` is
|
||||
used to express a difference, the ``tv_sec`` field may fall into a negative range.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user