1 /* 2 * Copyright (c) 2015 Wind River Systems, Inc. 3 * Copyright (c) 2019 Intel Corporation 4 * 5 * SPDX-License-Identifier: Apache-2.0 6 */ 7 8 /** 9 * @file 10 * @brief Timer driver API 11 * 12 * Declare API implemented by system timer driver and used by kernel components. 13 */ 14 15 #ifndef ZEPHYR_INCLUDE_DRIVERS_SYSTEM_TIMER_H_ 16 #define ZEPHYR_INCLUDE_DRIVERS_SYSTEM_TIMER_H_ 17 18 #include <stdbool.h> 19 #include <zephyr/types.h> 20 21 #ifdef __cplusplus 22 extern "C" { 23 #endif 24 25 #define SYS_CLOCK_MAX_WAIT (IS_ENABLED(CONFIG_SYSTEM_CLOCK_SLOPPY_IDLE) \ 26 ? K_TICKS_FOREVER : INT_MAX) 27 28 /** 29 * @brief System Clock APIs 30 * @defgroup clock_apis System Clock APIs 31 * @{ 32 */ 33 34 /** 35 * @brief Set system clock timeout 36 * 37 * Informs the system clock driver that the next needed call to 38 * sys_clock_announce() will not be until the specified number of ticks 39 * from the current time have elapsed. Note that spurious calls 40 * to sys_clock_announce() are allowed (i.e. it's legal to announce 41 * every tick and implement this function as a noop), the requirement 42 * is that one tick announcement should occur within one tick BEFORE 43 * the specified expiration (that is, passing ticks==1 means "announce 44 * the next tick", this convention was chosen to match legacy usage). 45 * Similarly a ticks value of zero (or even negative) is legal and 46 * treated identically: it simply indicates the kernel would like the 47 * next tick announcement as soon as possible. 48 * 49 * Note that ticks can also be passed the special value K_TICKS_FOREVER, 50 * indicating that no future timer interrupts are expected or required 51 * and that the system is permitted to enter an indefinite sleep even 52 * if this could cause rollover of the internal counter (i.e. the 53 * system uptime counter is allowed to be wrong 54 * 55 * Note also that it is conventional for the kernel to pass INT_MAX 56 * for ticks if it wants to preserve the uptime tick count but doesn't 57 * have a specific event to await. The intent here is that the driver 58 * will schedule any needed timeout as far into the future as 59 * possible. For the specific case of INT_MAX, the next call to 60 * sys_clock_announce() may occur at any point in the future, not just 61 * at INT_MAX ticks. But the correspondence between the announced 62 * ticks and real-world time must be correct. 63 * 64 * A final note about SMP: note that the call to sys_clock_set_timeout() 65 * is made on any CPU, and reflects the next timeout desired globally. 66 * The resulting calls(s) to sys_clock_announce() must be properly 67 * serialized by the driver such that a given tick is announced 68 * exactly once across the system. The kernel does not (cannot, 69 * really) attempt to serialize things by "assigning" timeouts to 70 * specific CPUs. 71 * 72 * @param ticks Timeout in tick units 73 * @param idle Hint to the driver that the system is about to enter 74 * the idle state immediately after setting the timeout 75 */ 76 void sys_clock_set_timeout(int32_t ticks, bool idle); 77 78 /** 79 * @brief Timer idle exit notification 80 * 81 * This notifies the timer driver that the system is exiting the idle 82 * and allows it to do whatever bookkeeping is needed to restore timer 83 * operation and compute elapsed ticks. 84 * 85 * @note Legacy timer drivers also use this opportunity to call back 86 * into sys_clock_announce() to notify the kernel of expired ticks. 87 * This is allowed for compatibility, but not recommended. The kernel 88 * will figure that out on its own. 89 */ 90 void sys_clock_idle_exit(void); 91 92 /** 93 * @brief Announce time progress to the kernel 94 * 95 * Informs the kernel that the specified number of ticks have elapsed 96 * since the last call to sys_clock_announce() (or system startup for 97 * the first call). The timer driver is expected to delivery these 98 * announcements as close as practical (subject to hardware and 99 * latency limitations) to tick boundaries. 100 * 101 * @param ticks Elapsed time, in ticks 102 */ 103 void sys_clock_announce(int32_t ticks); 104 105 /** 106 * @brief Ticks elapsed since last sys_clock_announce() call 107 * 108 * Queries the clock driver for the current time elapsed since the 109 * last call to sys_clock_announce() was made. The kernel will call 110 * this with appropriate locking, the driver needs only provide an 111 * instantaneous answer. 112 */ 113 uint32_t sys_clock_elapsed(void); 114 115 /** 116 * @brief Disable system timer. 117 * 118 * @note Not all system timer drivers has the capability of being disabled. 119 * The config @kconfig{CONFIG_SYSTEM_TIMER_HAS_DISABLE_SUPPORT} can be used to 120 * check if the system timer has the capability of being disabled. 121 */ 122 void sys_clock_disable(void); 123 124 /** 125 * @brief Hardware cycle counter 126 * 127 * Timer drivers are generally responsible for the system cycle 128 * counter as well as the tick announcements. This function is 129 * generally called out of the architecture layer (@see 130 * arch_k_cycle_get_32()) to implement the cycle counter, though the 131 * user-facing API is owned by the architecture, not the driver. The 132 * rate must match CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC. 133 * 134 * @note 135 * If the counter clock is large enough for this to wrap its full range 136 * within a few seconds (i.e. CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC is greater 137 * than 50Mhz) then it is recommended to also implement 138 * sys_clock_cycle_get_64(). 139 * 140 * @return The current cycle time. This should count up monotonically 141 * through the full 32 bit space, wrapping at 0xffffffff. Hardware 142 * with fewer bits of precision in the timer is expected to synthesize 143 * a 32 bit count. 144 */ 145 uint32_t sys_clock_cycle_get_32(void); 146 147 /** 148 * @brief 64 bit hardware cycle counter 149 * 150 * As for sys_clock_cycle_get_32(), but with a 64 bit return value. 151 * Not all hardware has 64 bit counters. This function need be 152 * implemented only if CONFIG_TIMER_HAS_64BIT_CYCLE_COUNTER is set. 153 * 154 * @note 155 * If the counter clock is large enough for sys_clock_cycle_get_32() to wrap 156 * its full range within a few seconds (i.e. CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC 157 * is greater than 50Mhz) then it is recommended to implement this API. 158 * 159 * @return The current cycle time. This should count up monotonically 160 * through the full 64 bit space, wrapping at 2^64-1. Hardware with 161 * fewer bits of precision in the timer is generally not expected to 162 * implement this API. 163 */ 164 uint64_t sys_clock_cycle_get_64(void); 165 166 /** 167 * @} 168 */ 169 170 #ifdef __cplusplus 171 } 172 #endif 173 174 #endif /* ZEPHYR_INCLUDE_DRIVERS_SYSTEM_TIMER_H_ */ 175