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