Line data Source code
1 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 0 : #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 1 : 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 1 : 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 1 : 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 1 : 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 1 : 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 1 : 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 1 : 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_ */
|