zephyr/doc/kernel/common/common_kernel_clocks.rst

145 lines
4.5 KiB
ReStructuredText

.. _common_kernel_clocks:
Kernel Clocks
#############
Concepts
********
The kernel supports two distinct clocks.
* A 64-bit *system clock*, which is the foundation for the kernel's
time-based services. This clock is a counter measured in *ticks*,
and increments at a frequency determined by the application.
The kernel allows this clock to be accessed directly by reading
the timer. It can also be accessed indirectly by using a kernel
timer or timeout capability.
* A 32-bit *hardware clock*, which is used as the source of the ticks
for the system clock. This clock is a counter measured in unspecified
units (called *cycles*), and increments at a frequency determined by
the hardware.
The kernel allows this clock to be accessed directly by reading
the timer.
The kernel also provides a number of variables that can be used
to convert the time units used by the clocks into standard time units
(e.g. seconds, milliseconds, nanoseconds, etc), and to convert between
the two types of clock time units.
Purpose
*******
Use the system clock for time-based processing that does not require
high precision, such as implementing time limits or time delays.
Use the hardware clock for time-based processing that requires higher
precision than the system clock can provide, such as fine-grained
time measurements.
.. note::
The high frequency of the hardware clock, combined with its 32-bit size,
means that counter rollover must be taken into account when taking
high-precision measurements over an extended period of time.
Usage
*****
Configuring the Kernel Clocks
=============================
Use the :option:`CONFIG_SYS_CLOCK_TICKS_PER_SEC` configuration option
to specify how many ticks occur every second. Setting this value
to zero disables all system clock and hardware clock capabilities.
.. note::
Making the system clock frequency value larger allows the system clock
to provide finer-grained timing, but also increases the amount of work
the kernel has to do to process ticks (since they occur more frequently).
Example: Measuring Time with Normal Precision
=============================================
This code uses the system clock to determine how many ticks have elapsed
between two points in time.
.. code-block:: c
int64_t time_stamp;
int64_t ticks_spent;
/* capture initial time stamp */
time_stamp = sys_tick_get();
/* do work for some (extended) period of time */
...
/* compute how long the work took & update time stamp */
ticks_spent = sys_tick_delta(&time_stamp);
Example: Measuring Time with High Precision
===========================================
This code uses the hardware clock to determine how many ticks have elapsed
between two points in time.
.. code-block:: c
uint32_t start_time;
uint32_t stop_time;
uint32_t cycles_spent;
uint32_t nanoseconds_spent;
/* capture initial time stamp */
start_time = sys_cycle_get_32();
/* do work for some (short) period of time */
...
/* capture final time stamp */
stop_time = sys_cycle_get_32();
/* compute how long the work took (assumes no counter rollover) */
cycles_spent = stop_time - start_time;
nanoseconds_spent = SYS_CLOCK_HW_CYCLES_TO_NS(cycles_spent);
APIs
****
Kernel clock APIs provided by :file:`microkernel.h`
===================================================
:cpp:func:`sys_tick_get()`, :cpp:func:`sys_tick_get_32()`
Read the system clock.
:cpp:func:`sys_tick_delta()`, :cpp:func:`sys_tick_delta_32()`
Compute the elapsed time since an earlier system clock reading.
Kernel clock APIs common to both :file:`microkernel.h`and :file:`nanokernel.h`
==============================================================================
:cpp:func:`sys_tick_get()`, :cpp:func:`sys_tick_get_32()`
Read the system clock.
:cpp:func:`sys_tick_delta()`, :cpp:func:`sys_tick_delta_32()`
Compute the elapsed time since an earlier system clock reading.
:cpp:func:`sys_cycle_get_32()`
Read hardware clock.
Kernel clock variables common to both :file:`microkernel.h` and :file:`nanokernel.h`
====================================================================================
:c:data:`sys_clock_ticks_per_sec`
The number of system clock ticks in a single second.
:c:data:`sys_clock_hw_cycles_per_sec`
The number of hardware clock cycles in a single second.
:c:data:`sys_clock_us_per_tick`
The number of microseconds in a single system clock tick.
:c:data:`sys_clock_hw_cycles_per_tick`
The number of hardware clock cycles in a single system clock tick.