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 <device.h> 20 #include <stdbool.h> 21 22 #ifdef __cplusplus 23 extern "C" { 24 #endif 25 26 /** 27 * @brief Clock APIs 28 * @defgroup clock_apis Clock APIs 29 * @{ 30 */ 31 32 /** 33 * @brief Initialize system clock driver 34 * 35 * The system clock is a Zephyr device created globally. This is its 36 * initialization callback. It is a weak symbol that will be 37 * implemented as a noop if undefined in the clock driver. 38 */ 39 extern int sys_clock_driver_init(const struct device *dev); 40 41 /** 42 * @brief Initialize system clock driver 43 * 44 * The system clock is a Zephyr device created globally. This is its 45 * device control callback, used in a few devices for power 46 * management. It is a weak symbol that will be implemented as a noop 47 * if undefined in the clock driver. 48 */ 49 extern int clock_device_ctrl(const struct device *dev, 50 enum pm_device_state state); 51 52 /** 53 * @brief Set system clock timeout 54 * 55 * Informs the system clock driver that the next needed call to 56 * sys_clock_announce() will not be until the specified number of ticks 57 * from the the current time have elapsed. Note that spurious calls 58 * to sys_clock_announce() are allowed (i.e. it's legal to announce 59 * every tick and implement this function as a noop), the requirement 60 * is that one tick announcement should occur within one tick BEFORE 61 * the specified expiration (that is, passing ticks==1 means "announce 62 * the next tick", this convention was chosen to match legacy usage). 63 * Similarly a ticks value of zero (or even negative) is legal and 64 * treated identically: it simply indicates the kernel would like the 65 * next tick announcement as soon as possible. 66 * 67 * Note that ticks can also be passed the special value K_TICKS_FOREVER, 68 * indicating that no future timer interrupts are expected or required 69 * and that the system is permitted to enter an indefinite sleep even 70 * if this could cause rollover of the internal counter (i.e. the 71 * system uptime counter is allowed to be wrong 72 * 73 * Note also that it is conventional for the kernel to pass INT_MAX 74 * for ticks if it wants to preserve the uptime tick count but doesn't 75 * have a specific event to await. The intent here is that the driver 76 * will schedule any needed timeout as far into the future as 77 * possible. For the specific case of INT_MAX, the next call to 78 * sys_clock_announce() may occur at any point in the future, not just 79 * at INT_MAX ticks. But the correspondence between the announced 80 * ticks and real-world time must be correct. 81 * 82 * A final note about SMP: note that the call to sys_clock_set_timeout() 83 * is made on any CPU, and reflects the next timeout desired globally. 84 * The resulting calls(s) to sys_clock_announce() must be properly 85 * serialized by the driver such that a given tick is announced 86 * exactly once across the system. The kernel does not (cannot, 87 * really) attempt to serialize things by "assigning" timeouts to 88 * specific CPUs. 89 * 90 * @param ticks Timeout in tick units 91 * @param idle Hint to the driver that the system is about to enter 92 * the idle state immediately after setting the timeout 93 */ 94 extern void sys_clock_set_timeout(int32_t ticks, bool idle); 95 96 /** 97 * @brief Timer idle exit notification 98 * 99 * This notifies the timer driver that the system is exiting the idle 100 * and allows it to do whatever bookkeeping is needed to restore timer 101 * operation and compute elapsed ticks. 102 * 103 * @note Legacy timer drivers also use this opportunity to call back 104 * into sys_clock_announce() to notify the kernel of expired ticks. 105 * This is allowed for compatibility, but not recommended. The kernel 106 * will figure that out on its own. 107 */ 108 extern void sys_clock_idle_exit(void); 109 110 /** 111 * @brief Announce time progress to the kernel 112 * 113 * Informs the kernel that the specified number of ticks have elapsed 114 * since the last call to sys_clock_announce() (or system startup for 115 * the first call). The timer driver is expected to delivery these 116 * announcements as close as practical (subject to hardware and 117 * latency limitations) to tick boundaries. 118 * 119 * @param ticks Elapsed time, in ticks 120 */ 121 extern void sys_clock_announce(int32_t ticks); 122 123 /** 124 * @brief Ticks elapsed since last sys_clock_announce() call 125 * 126 * Queries the clock driver for the current time elapsed since the 127 * last call to sys_clock_announce() was made. The kernel will call 128 * this with appropriate locking, the driver needs only provide an 129 * instantaneous answer. 130 */ 131 extern uint32_t sys_clock_elapsed(void); 132 /** 133 * @} 134 */ 135 136 #ifdef __cplusplus 137 } 138 #endif 139 140 #endif /* ZEPHYR_INCLUDE_DRIVERS_SYSTEM_TIMER_H_ */ 141