Inaky Perez-Gonzalez | 8ddf82c | 2015-04-10 16:44:37 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2014-2015 Wind River Systems, Inc. |
| 3 | * |
David B. Kinder | ac74d8b | 2017-01-18 17:01:01 -0800 | [diff] [blame] | 4 | * SPDX-License-Identifier: Apache-2.0 |
Inaky Perez-Gonzalez | 8ddf82c | 2015-04-10 16:44:37 -0700 | [diff] [blame] | 5 | */ |
| 6 | |
Anas Nashif | 275ca60 | 2015-12-04 10:09:39 -0500 | [diff] [blame] | 7 | /** |
| 8 | * @file |
Anas Nashif | 59c7ecb | 2021-03-13 08:05:09 -0500 | [diff] [blame] | 9 | * @brief Variables needed for system clock |
Anas Nashif | 275ca60 | 2015-12-04 10:09:39 -0500 | [diff] [blame] | 10 | * |
Dan Kalowsky | da67b29 | 2015-10-20 09:42:33 -0700 | [diff] [blame] | 11 | * |
| 12 | * Declare variables used by both system timer device driver and kernel |
| 13 | * components that use timer functionality. |
Anas Nashif | ea0d0b2 | 2015-07-01 17:22:39 -0400 | [diff] [blame] | 14 | */ |
Inaky Perez-Gonzalez | 8ddf82c | 2015-04-10 16:44:37 -0700 | [diff] [blame] | 15 | |
Flavio Ceolin | 67ca176 | 2018-09-14 10:43:44 -0700 | [diff] [blame] | 16 | #ifndef ZEPHYR_INCLUDE_SYS_CLOCK_H_ |
| 17 | #define ZEPHYR_INCLUDE_SYS_CLOCK_H_ |
Inaky Perez-Gonzalez | 8ddf82c | 2015-04-10 16:44:37 -0700 | [diff] [blame] | 18 | |
Anas Nashif | a2fd7d7 | 2019-06-26 10:33:55 -0400 | [diff] [blame] | 19 | #include <sys/util.h> |
Anas Nashif | ee9dd1a | 2019-06-26 10:33:41 -0400 | [diff] [blame] | 20 | #include <sys/dlist.h> |
Andy Ross | 0d1228a | 2018-09-19 09:35:43 -0700 | [diff] [blame] | 21 | |
Peter Bigot | 6554a5e | 2019-08-12 12:54:52 -0500 | [diff] [blame] | 22 | #include <toolchain.h> |
| 23 | #include <zephyr/types.h> |
| 24 | |
Peter Bigot | 5f34700 | 2019-10-31 06:16:00 -0500 | [diff] [blame] | 25 | #include <sys/time_units.h> |
Andy Ross | 370c395 | 2019-06-28 11:16:50 -0700 | [diff] [blame] | 26 | |
Peter Mitsis | a0e4568 | 2016-01-22 12:38:49 -0500 | [diff] [blame] | 27 | #ifdef __cplusplus |
| 28 | extern "C" { |
| 29 | #endif |
| 30 | |
Andy Ross | 7832738 | 2020-03-05 15:18:14 -0800 | [diff] [blame] | 31 | /** |
| 32 | * @addtogroup clock_apis |
| 33 | * @{ |
| 34 | */ |
| 35 | |
Andy Ross | cfeb07e | 2020-03-05 21:14:02 -0800 | [diff] [blame] | 36 | /** |
| 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 Gala | a1b77fd | 2020-05-27 11:26:57 -0500 | [diff] [blame] | 46 | typedef int64_t k_ticks_t; |
Andy Ross | cfeb07e | 2020-03-05 21:14:02 -0800 | [diff] [blame] | 47 | #else |
Kumar Gala | a1b77fd | 2020-05-27 11:26:57 -0500 | [diff] [blame] | 48 | typedef uint32_t k_ticks_t; |
Andy Ross | cfeb07e | 2020-03-05 21:14:02 -0800 | [diff] [blame] | 49 | #endif |
Andy Ross | 7832738 | 2020-03-05 15:18:14 -0800 | [diff] [blame] | 50 | |
| 51 | #define K_TICKS_FOREVER ((k_ticks_t) -1) |
| 52 | |
Andy Ross | e39bf29 | 2020-03-19 10:30:33 -0700 | [diff] [blame] | 53 | /** |
| 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 Ross | 7832738 | 2020-03-05 15:18:14 -0800 | [diff] [blame] | 65 | typedef 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 Leung | df6e80a | 2022-01-19 16:04:21 -0800 | [diff] [blame] | 82 | #define Z_TIMEOUT_NO_WAIT ((k_timeout_t) {0}) |
Artur Lipowski | ca61606 | 2020-12-16 10:52:14 +0100 | [diff] [blame] | 83 | #if defined(__cplusplus) && ((__cplusplus - 0) < 202002L) |
| 84 | #define Z_TIMEOUT_TICKS(t) ((k_timeout_t) { (t) }) |
| 85 | #else |
Andy Ross | 7832738 | 2020-03-05 15:18:14 -0800 | [diff] [blame] | 86 | #define Z_TIMEOUT_TICKS(t) ((k_timeout_t) { .ticks = (t) }) |
Artur Lipowski | ca61606 | 2020-12-16 10:52:14 +0100 | [diff] [blame] | 87 | #endif |
Andy Ross | 7832738 | 2020-03-05 15:18:14 -0800 | [diff] [blame] | 88 | #define Z_FOREVER Z_TIMEOUT_TICKS(K_TICKS_FOREVER) |
Andy Ross | 150e18d | 2020-06-17 08:56:40 -0700 | [diff] [blame] | 89 | |
| 90 | #ifdef CONFIG_TIMEOUT_64BIT |
Artur Lipowski | 2cee0b2 | 2020-06-29 08:48:54 +0200 | [diff] [blame] | 91 | # 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 Ross | 150e18d | 2020-06-17 08:56:40 -0700 | [diff] [blame] | 95 | #else |
Artur Lipowski | 2cee0b2 | 2020-06-29 08:48:54 +0200 | [diff] [blame] | 96 | # 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 Ross | 150e18d | 2020-06-17 08:56:40 -0700 | [diff] [blame] | 100 | #endif |
Andy Ross | 7832738 | 2020-03-05 15:18:14 -0800 | [diff] [blame] | 101 | |
Andy Ross | 4c7b77a | 2020-03-09 09:35:35 -0700 | [diff] [blame] | 102 | /* 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 Kazakov | 9713f0d | 2022-02-24 12:00:55 +0000 | [diff] [blame] | 105 | * value was an absolute timeout with the returned expiration time. |
Andy Ross | 4c7b77a | 2020-03-09 09:35:35 -0700 | [diff] [blame] | 106 | * 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 Ross | 7832738 | 2020-03-05 15:18:14 -0800 | [diff] [blame] | 112 | /** @} */ |
| 113 | |
Andy Ross | 220d4f83 | 2018-09-19 10:52:07 -0700 | [diff] [blame] | 114 | #ifdef CONFIG_TICKLESS_KERNEL |
Patrik Flykt | 4344e27 | 2019-03-08 14:19:05 -0700 | [diff] [blame] | 115 | extern void z_enable_sys_clock(void); |
Ramesh Thomas | 89ffd44 | 2017-02-05 19:37:19 -0800 | [diff] [blame] | 116 | #endif |
Benjamin Walsh | fde6458 | 2015-11-20 16:26:25 -0500 | [diff] [blame] | 117 | |
Andy Ross | 0d1228a | 2018-09-19 09:35:43 -0700 | [diff] [blame] | 118 | #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 Ceolin | f1f82a8 | 2018-12-04 15:13:27 -0800 | [diff] [blame] | 124 | #define NSEC_PER_USEC 1000U |
Andy Ross | 0d1228a | 2018-09-19 09:35:43 -0700 | [diff] [blame] | 125 | |
| 126 | /* number of microseconds per millisecond */ |
Flavio Ceolin | f1f82a8 | 2018-12-04 15:13:27 -0800 | [diff] [blame] | 127 | #define USEC_PER_MSEC 1000U |
Andy Ross | 0d1228a | 2018-09-19 09:35:43 -0700 | [diff] [blame] | 128 | |
| 129 | /* number of milliseconds per second */ |
Flavio Ceolin | f1f82a8 | 2018-12-04 15:13:27 -0800 | [diff] [blame] | 130 | #define MSEC_PER_SEC 1000U |
Andy Ross | 0d1228a | 2018-09-19 09:35:43 -0700 | [diff] [blame] | 131 | |
| 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 Ross | 0d1228a | 2018-09-19 09:35:43 -0700 | [diff] [blame] | 141 | /* |
Charles E. Youse | e1cb4ca | 2019-05-07 15:53:51 -0700 | [diff] [blame] | 142 | * 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 Ross | 0d1228a | 2018-09-19 09:35:43 -0700 | [diff] [blame] | 145 | */ |
| 146 | |
Charles E. Youse | e1cb4ca | 2019-05-07 15:53:51 -0700 | [diff] [blame] | 147 | #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 Ross | 0d1228a | 2018-09-19 09:35:43 -0700 | [diff] [blame] | 153 | #endif |
| 154 | |
Andy Ross | 0d1228a | 2018-09-19 09:35:43 -0700 | [diff] [blame] | 155 | #endif |
| 156 | |
Andy Ross | 0d1228a | 2018-09-19 09:35:43 -0700 | [diff] [blame] | 157 | /* added tick needed to account for tick in progress */ |
Andy Ross | 0d1228a | 2018-09-19 09:35:43 -0700 | [diff] [blame] | 158 | #define _TICK_ALIGN 1 |
Andy Ross | 0d1228a | 2018-09-19 09:35:43 -0700 | [diff] [blame] | 159 | |
Dmitriy Korovkin | f51049b | 2015-04-10 17:16:14 -0400 | [diff] [blame] | 160 | /* |
| 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 Gala | a1b77fd | 2020-05-27 11:26:57 -0500 | [diff] [blame] | 165 | (uint32_t)(k_cyc_to_ns_floor64(X) / NCYCLES) |
Dmitriy Korovkin | f51049b | 2015-04-10 17:16:14 -0400 | [diff] [blame] | 166 | |
Allan Stephens | c2f15a4 | 2016-11-17 12:24:22 -0500 | [diff] [blame] | 167 | /** |
Andy Ross | 317178b | 2018-09-19 14:17:00 -0700 | [diff] [blame] | 168 | * |
| 169 | * @brief Return the lower part of the current system tick count |
| 170 | * |
| 171 | * @return the current system tick count |
| 172 | * |
| 173 | */ |
Anas Nashif | 5c90ceb | 2021-03-13 08:19:53 -0500 | [diff] [blame] | 174 | uint32_t sys_clock_tick_get_32(void); |
Andy Ross | 317178b | 2018-09-19 14:17:00 -0700 | [diff] [blame] | 175 | |
| 176 | /** |
| 177 | * |
| 178 | * @brief Return the current system tick count |
| 179 | * |
| 180 | * @return the current system tick count |
| 181 | * |
| 182 | */ |
Anas Nashif | fe0872c | 2021-03-13 08:21:21 -0500 | [diff] [blame] | 183 | int64_t sys_clock_tick_get(void); |
Andy Ross | 317178b | 2018-09-19 14:17:00 -0700 | [diff] [blame] | 184 | |
Andy Ross | 987c0e5 | 2018-09-27 16:50:00 -0700 | [diff] [blame] | 185 | #ifndef CONFIG_SYS_CLOCK_EXISTS |
Anas Nashif | fe0872c | 2021-03-13 08:21:21 -0500 | [diff] [blame] | 186 | #define sys_clock_tick_get() (0) |
Anas Nashif | 5c90ceb | 2021-03-13 08:19:53 -0500 | [diff] [blame] | 187 | #define sys_clock_tick_get_32() (0) |
Andy Ross | 987c0e5 | 2018-09-27 16:50:00 -0700 | [diff] [blame] | 188 | #endif |
Inaky Perez-Gonzalez | 8ddf82c | 2015-04-10 16:44:37 -0700 | [diff] [blame] | 189 | |
Anas Nashif | a518f48 | 2021-03-13 08:22:38 -0500 | [diff] [blame] | 190 | uint64_t sys_clock_timeout_end_calc(k_timeout_t timeout); |
Andy Ross | 7832738 | 2020-03-05 15:18:14 -0800 | [diff] [blame] | 191 | |
Peter Mitsis | a0e4568 | 2016-01-22 12:38:49 -0500 | [diff] [blame] | 192 | #ifdef __cplusplus |
| 193 | } |
| 194 | #endif |
| 195 | |
Flavio Ceolin | 67ca176 | 2018-09-14 10:43:44 -0700 | [diff] [blame] | 196 | #endif /* ZEPHYR_INCLUDE_SYS_CLOCK_H_ */ |