145 lines
4.5 KiB
ReStructuredText
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.
|