blob: 4de2391afa068cae28ba82cb62c37090d420ceda [file] [log] [blame]
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07001/*
2 * Copyright (c) 2014-2015 Wind River Systems, Inc.
3 *
David B. Kinderac74d8b2017-01-18 17:01:01 -08004 * SPDX-License-Identifier: Apache-2.0
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005 */
6
Anas Nashif275ca602015-12-04 10:09:39 -05007/**
8 * @file
Anas Nashif59c7ecb2021-03-13 08:05:09 -05009 * @brief Variables needed for system clock
Anas Nashif275ca602015-12-04 10:09:39 -050010 *
Dan Kalowskyda67b292015-10-20 09:42:33 -070011 *
12 * Declare variables used by both system timer device driver and kernel
13 * components that use timer functionality.
Anas Nashifea0d0b22015-07-01 17:22:39 -040014 */
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -070015
Flavio Ceolin67ca1762018-09-14 10:43:44 -070016#ifndef ZEPHYR_INCLUDE_SYS_CLOCK_H_
17#define ZEPHYR_INCLUDE_SYS_CLOCK_H_
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -070018
Anas Nashifa2fd7d72019-06-26 10:33:55 -040019#include <sys/util.h>
Anas Nashifee9dd1a2019-06-26 10:33:41 -040020#include <sys/dlist.h>
Andy Ross0d1228a2018-09-19 09:35:43 -070021
Peter Bigot6554a5e2019-08-12 12:54:52 -050022#include <toolchain.h>
23#include <zephyr/types.h>
24
Peter Bigot5f347002019-10-31 06:16:00 -050025#include <sys/time_units.h>
Andy Ross370c3952019-06-28 11:16:50 -070026
Peter Mitsisa0e45682016-01-22 12:38:49 -050027#ifdef __cplusplus
28extern "C" {
29#endif
30
Andy Ross78327382020-03-05 15:18:14 -080031/**
32 * @addtogroup clock_apis
33 * @{
34 */
35
Andy Rosscfeb07e2020-03-05 21:14:02 -080036/**
37 * @brief Tick precision used in timeout APIs
38 *
39 * This type defines the word size of the timeout values used in
40 * k_timeout_t objects, and thus defines an upper bound on maximum
41 * timeout length (or equivalently minimum tick duration). Note that
42 * this does not affect the size of the system uptime counter, which
43 * is always a 64 bit count of ticks.
44 */
45#ifdef CONFIG_TIMEOUT_64BIT
Kumar Galaa1b77fd2020-05-27 11:26:57 -050046typedef int64_t k_ticks_t;
Andy Rosscfeb07e2020-03-05 21:14:02 -080047#else
Kumar Galaa1b77fd2020-05-27 11:26:57 -050048typedef uint32_t k_ticks_t;
Andy Rosscfeb07e2020-03-05 21:14:02 -080049#endif
Andy Ross78327382020-03-05 15:18:14 -080050
51#define K_TICKS_FOREVER ((k_ticks_t) -1)
52
Andy Rosse39bf292020-03-19 10:30:33 -070053/**
54 * @brief Kernel timeout type
55 *
56 * Timeout arguments presented to kernel APIs are stored in this
57 * opaque type, which is capable of representing times in various
58 * formats and units. It should be constructed from application data
59 * using one of the macros defined for this purpose (e.g. `K_MSEC()`,
60 * `K_TIMEOUT_ABS_TICKS()`, etc...), or be one of the two constants
61 * K_NO_WAIT or K_FOREVER. Applications should not inspect the
62 * internal data once constructed. Timeout values may be compared for
63 * equality with the `K_TIMEOUT_EQ()` macro.
64 */
Andy Ross78327382020-03-05 15:18:14 -080065typedef struct {
66 k_ticks_t ticks;
67} k_timeout_t;
68
69/**
70 * @brief Compare timeouts for equality
71 *
72 * The k_timeout_t object is an opaque struct that should not be
73 * inspected by application code. This macro exists so that users can
74 * test timeout objects for equality with known constants
75 * (e.g. K_NO_WAIT and K_FOREVER) when implementing their own APIs in
76 * terms of Zephyr timeout constants.
77 *
78 * @return True if the timeout objects are identical
79 */
80#define K_TIMEOUT_EQ(a, b) ((a).ticks == (b).ticks)
81
Daniel Leungdf6e80a2022-01-19 16:04:21 -080082#define Z_TIMEOUT_NO_WAIT ((k_timeout_t) {0})
Artur Lipowskica616062020-12-16 10:52:14 +010083#if defined(__cplusplus) && ((__cplusplus - 0) < 202002L)
84#define Z_TIMEOUT_TICKS(t) ((k_timeout_t) { (t) })
85#else
Andy Ross78327382020-03-05 15:18:14 -080086#define Z_TIMEOUT_TICKS(t) ((k_timeout_t) { .ticks = (t) })
Artur Lipowskica616062020-12-16 10:52:14 +010087#endif
Andy Ross78327382020-03-05 15:18:14 -080088#define Z_FOREVER Z_TIMEOUT_TICKS(K_TICKS_FOREVER)
Andy Ross150e18d2020-06-17 08:56:40 -070089
90#ifdef CONFIG_TIMEOUT_64BIT
Artur Lipowski2cee0b22020-06-29 08:48:54 +020091# define Z_TIMEOUT_MS(t) Z_TIMEOUT_TICKS((k_ticks_t)k_ms_to_ticks_ceil64(MAX(t, 0)))
92# define Z_TIMEOUT_US(t) Z_TIMEOUT_TICKS((k_ticks_t)k_us_to_ticks_ceil64(MAX(t, 0)))
93# define Z_TIMEOUT_NS(t) Z_TIMEOUT_TICKS((k_ticks_t)k_ns_to_ticks_ceil64(MAX(t, 0)))
94# define Z_TIMEOUT_CYC(t) Z_TIMEOUT_TICKS((k_ticks_t)k_cyc_to_ticks_ceil64(MAX(t, 0)))
Andy Ross150e18d2020-06-17 08:56:40 -070095#else
Artur Lipowski2cee0b22020-06-29 08:48:54 +020096# define Z_TIMEOUT_MS(t) Z_TIMEOUT_TICKS((k_ticks_t)k_ms_to_ticks_ceil32(MAX(t, 0)))
97# define Z_TIMEOUT_US(t) Z_TIMEOUT_TICKS((k_ticks_t)k_us_to_ticks_ceil32(MAX(t, 0)))
98# define Z_TIMEOUT_NS(t) Z_TIMEOUT_TICKS((k_ticks_t)k_ns_to_ticks_ceil32(MAX(t, 0)))
99# define Z_TIMEOUT_CYC(t) Z_TIMEOUT_TICKS((k_ticks_t)k_cyc_to_ticks_ceil32(MAX(t, 0)))
Andy Ross150e18d2020-06-17 08:56:40 -0700100#endif
Andy Ross78327382020-03-05 15:18:14 -0800101
Andy Ross4c7b77a2020-03-09 09:35:35 -0700102/* Converts between absolute timeout expiration values (packed into
103 * the negative space below K_TICKS_FOREVER) and (non-negative) delta
104 * timeout values. If the result of Z_TICK_ABS(t) is >= 0, then the
Nazar Kazakov9713f0d2022-02-24 12:00:55 +0000105 * value was an absolute timeout with the returned expiration time.
Andy Ross4c7b77a2020-03-09 09:35:35 -0700106 * Note that this macro is bidirectional: Z_TICK_ABS(Z_TICK_ABS(t)) ==
107 * t for all inputs, and that the representation of K_TICKS_FOREVER is
108 * the same value in both spaces! Clever, huh?
109 */
110#define Z_TICK_ABS(t) (K_TICKS_FOREVER - 1 - (t))
111
Andy Ross78327382020-03-05 15:18:14 -0800112/** @} */
113
Andy Ross220d4f832018-09-19 10:52:07 -0700114#ifdef CONFIG_TICKLESS_KERNEL
Patrik Flykt4344e272019-03-08 14:19:05 -0700115extern void z_enable_sys_clock(void);
Ramesh Thomas89ffd442017-02-05 19:37:19 -0800116#endif
Benjamin Walshfde64582015-11-20 16:26:25 -0500117
Andy Ross0d1228a2018-09-19 09:35:43 -0700118#if defined(CONFIG_SYS_CLOCK_EXISTS) && \
119 (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC == 0)
120#error "SYS_CLOCK_HW_CYCLES_PER_SEC must be non-zero!"
121#endif
122
123/* number of nsec per usec */
Flavio Ceolinf1f82a82018-12-04 15:13:27 -0800124#define NSEC_PER_USEC 1000U
Andy Ross0d1228a2018-09-19 09:35:43 -0700125
126/* number of microseconds per millisecond */
Flavio Ceolinf1f82a82018-12-04 15:13:27 -0800127#define USEC_PER_MSEC 1000U
Andy Ross0d1228a2018-09-19 09:35:43 -0700128
129/* number of milliseconds per second */
Flavio Ceolinf1f82a82018-12-04 15:13:27 -0800130#define MSEC_PER_SEC 1000U
Andy Ross0d1228a2018-09-19 09:35:43 -0700131
132/* number of microseconds per second */
133#define USEC_PER_SEC ((USEC_PER_MSEC) * (MSEC_PER_SEC))
134
135/* number of nanoseconds per second */
136#define NSEC_PER_SEC ((NSEC_PER_USEC) * (USEC_PER_MSEC) * (MSEC_PER_SEC))
137
138
139/* kernel clocks */
140
Andy Ross0d1228a2018-09-19 09:35:43 -0700141/*
Charles E. Yousee1cb4ca2019-05-07 15:53:51 -0700142 * We default to using 64-bit intermediates in timescale conversions,
143 * but if the HW timer cycles/sec, ticks/sec and ms/sec are all known
144 * to be nicely related, then we can cheat with 32 bits instead.
Andy Ross0d1228a2018-09-19 09:35:43 -0700145 */
146
Charles E. Yousee1cb4ca2019-05-07 15:53:51 -0700147#ifdef CONFIG_SYS_CLOCK_EXISTS
148
149#if defined(CONFIG_TIMER_READS_ITS_FREQUENCY_AT_RUNTIME) || \
150 (MSEC_PER_SEC % CONFIG_SYS_CLOCK_TICKS_PER_SEC) || \
151 (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC % CONFIG_SYS_CLOCK_TICKS_PER_SEC)
152#define _NEED_PRECISE_TICK_MS_CONVERSION
Andy Ross0d1228a2018-09-19 09:35:43 -0700153#endif
154
Andy Ross0d1228a2018-09-19 09:35:43 -0700155#endif
156
Andy Ross0d1228a2018-09-19 09:35:43 -0700157/* added tick needed to account for tick in progress */
Andy Ross0d1228a2018-09-19 09:35:43 -0700158#define _TICK_ALIGN 1
Andy Ross0d1228a2018-09-19 09:35:43 -0700159
Dmitriy Korovkinf51049b2015-04-10 17:16:14 -0400160/*
161 * SYS_CLOCK_HW_CYCLES_TO_NS_AVG converts CPU clock cycles to nanoseconds
162 * and calculates the average cycle time
163 */
164#define SYS_CLOCK_HW_CYCLES_TO_NS_AVG(X, NCYCLES) \
Kumar Galaa1b77fd2020-05-27 11:26:57 -0500165 (uint32_t)(k_cyc_to_ns_floor64(X) / NCYCLES)
Dmitriy Korovkinf51049b2015-04-10 17:16:14 -0400166
Allan Stephensc2f15a42016-11-17 12:24:22 -0500167/**
Andy Ross317178b2018-09-19 14:17:00 -0700168 *
169 * @brief Return the lower part of the current system tick count
170 *
171 * @return the current system tick count
172 *
173 */
Anas Nashif5c90ceb2021-03-13 08:19:53 -0500174uint32_t sys_clock_tick_get_32(void);
Andy Ross317178b2018-09-19 14:17:00 -0700175
176/**
177 *
178 * @brief Return the current system tick count
179 *
180 * @return the current system tick count
181 *
182 */
Anas Nashiffe0872c2021-03-13 08:21:21 -0500183int64_t sys_clock_tick_get(void);
Andy Ross317178b2018-09-19 14:17:00 -0700184
Andy Ross987c0e52018-09-27 16:50:00 -0700185#ifndef CONFIG_SYS_CLOCK_EXISTS
Anas Nashiffe0872c2021-03-13 08:21:21 -0500186#define sys_clock_tick_get() (0)
Anas Nashif5c90ceb2021-03-13 08:19:53 -0500187#define sys_clock_tick_get_32() (0)
Andy Ross987c0e52018-09-27 16:50:00 -0700188#endif
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700189
Anas Nashifa518f482021-03-13 08:22:38 -0500190uint64_t sys_clock_timeout_end_calc(k_timeout_t timeout);
Andy Ross78327382020-03-05 15:18:14 -0800191
Peter Mitsisa0e45682016-01-22 12:38:49 -0500192#ifdef __cplusplus
193}
194#endif
195
Flavio Ceolin67ca1762018-09-14 10:43:44 -0700196#endif /* ZEPHYR_INCLUDE_SYS_CLOCK_H_ */