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 | /* * 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 <device.h> #include <stdbool.h> #ifdef __cplusplus extern "C" { #endif /** * @brief Clock APIs * @defgroup clock_apis Clock APIs * @{ */ /** * @brief Initialize system clock driver * * The system clock is a Zephyr device created globally. This is its * initialization callback. It is a weak symbol that will be * implemented as a noop if undefined in the clock driver. */ extern int sys_clock_driver_init(const struct device *dev); /** * @brief Initialize system clock driver * * The system clock is a Zephyr device created globally. This is its * device control callback, used in a few devices for power * management. It is a weak symbol that will be implemented as a noop * if undefined in the clock driver. */ extern int clock_device_ctrl(const struct device *dev, enum pm_device_state state); /** * @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); /** * @} */ #ifdef __cplusplus } #endif #endif /* ZEPHYR_INCLUDE_DRIVERS_SYSTEM_TIMER_H_ */ |