1 /*
2 * Copyright (c) 2016, Wind River Systems, Inc.
3 * Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 #ifndef _BLE_MESH_TIMER_H_
9 #define _BLE_MESH_TIMER_H_
10
11 #include "mesh_types.h"
12 #include "mesh_slist.h"
13 #include "mesh_atomic.h"
14
15 #ifdef __cplusplus
16 extern "C" {
17 #endif
18
19 /* number of nsec per usec */
20 #define NSEC_PER_USEC 1000
21
22 /* number of microseconds per millisecond */
23 #define USEC_PER_MSEC 1000
24
25 /* number of milliseconds per second */
26 #define MSEC_PER_SEC 1000
27
28 /* number of microseconds per second */
29 #define USEC_PER_SEC ((USEC_PER_MSEC) * (MSEC_PER_SEC))
30
31 /* number of nanoseconds per second */
32 #define NSEC_PER_SEC ((NSEC_PER_USEC) * (USEC_PER_MSEC) * (MSEC_PER_SEC))
33
34 /* timeout is not in use */
35 #define _INACTIVE (-1)
36
37 struct k_work;
38
39 /**
40 * @typedef k_work_handler_t
41 * @brief Work item handler function type.
42 *
43 * A work item's handler function is executed by a workqueue's thread
44 * when the work item is processed by the workqueue.
45 *
46 * @param work Address of the work item.
47 *
48 * @return N/A
49 */
50 typedef void (*k_work_handler_t)(struct k_work *work);
51
52 struct k_work {
53 void *_reserved;
54 k_work_handler_t handler;
55 int index;
56 };
57
58 #define _K_WORK_INITIALIZER(work_handler) \
59 { \
60 ._reserved = NULL, \
61 .handler = work_handler, \
62 }
63
64 /**
65 * @brief Generate null timeout delay.
66 *
67 * This macro generates a timeout delay that that instructs a kernel API
68 * not to wait if the requested operation cannot be performed immediately.
69 *
70 * @return Timeout delay value.
71 */
72 #define K_NO_WAIT 0
73
74 /**
75 * @brief Generate timeout delay from milliseconds.
76 *
77 * This macro generates a timeout delay that that instructs a kernel API
78 * to wait up to @a ms milliseconds to perform the requested operation.
79 *
80 * @param ms Duration in milliseconds.
81 *
82 * @return Timeout delay value.
83 */
84 #define K_MSEC(ms) (ms)
85
86 /**
87 * @brief Generate timeout delay from seconds.
88 *
89 * This macro generates a timeout delay that that instructs a kernel API
90 * to wait up to @a s seconds to perform the requested operation.
91 *
92 * @param s Duration in seconds.
93 *
94 * @return Timeout delay value.
95 */
96 #define K_SECONDS(s) K_MSEC((s) * MSEC_PER_SEC)
97
98 /**
99 * @brief Generate timeout delay from minutes.
100 *
101 * This macro generates a timeout delay that that instructs a kernel API
102 * to wait up to @a m minutes to perform the requested operation.
103 *
104 * @param m Duration in minutes.
105 *
106 * @return Timeout delay value.
107 */
108 #define K_MINUTES(m) K_SECONDS((m) * 60)
109
110 /**
111 * @brief Generate timeout delay from hours.
112 *
113 * This macro generates a timeout delay that that instructs a kernel API
114 * to wait up to @a h hours to perform the requested operation.
115 *
116 * @param h Duration in hours.
117 *
118 * @return Timeout delay value.
119 */
120 #define K_HOURS(h) K_MINUTES((h) * 60)
121
122 /**
123 * @brief Generate infinite timeout delay.
124 *
125 * This macro generates a timeout delay that that instructs a kernel API
126 * to wait as long as necessary to perform the requested operation.
127 *
128 * @return Timeout delay value.
129 */
130 #define K_FOREVER (-1)
131
132 /**
133 * @brief Get system uptime (32-bit version).
134 *
135 * This routine returns the lower 32-bits of the elapsed time since the system
136 * booted, in milliseconds.
137 *
138 * This routine can be more efficient than k_uptime_get(), as it reduces the
139 * need for interrupt locking and 64-bit math. However, the 32-bit result
140 * cannot hold a system uptime time larger than approximately 50 days, so the
141 * caller must handle possible rollovers.
142 *
143 * @return Current uptime.
144 */
145 uint32_t k_uptime_get_32(void);
146
147 struct k_delayed_work {
148 struct k_work work;
149 };
150
151 /**
152 * @brief Submit a delayed work item to the system workqueue.
153 *
154 * This routine schedules work item @a work to be processed by the system
155 * workqueue after a delay of @a delay milliseconds. The routine initiates
156 * an asynchronous countdown for the work item and then returns to the caller.
157 * Only when the countdown completes is the work item actually submitted to
158 * the workqueue and becomes pending.
159 *
160 * Submitting a previously submitted delayed work item that is still
161 * counting down cancels the existing submission and restarts the countdown
162 * using the new delay. If the work item is currently pending on the
163 * workqueue's queue because the countdown has completed it is too late to
164 * resubmit the item, and resubmission fails without impacting the work item.
165 * If the work item has already been processed, or is currently being processed,
166 * its work is considered complete and the work item can be resubmitted.
167 *
168 * @warning
169 * Work items submitted to the system workqueue should avoid using handlers
170 * that block or yield since this may prevent the system workqueue from
171 * processing other work items in a timely manner.
172 *
173 * @note Can be called by ISRs.
174 *
175 * @param work Address of delayed work item.
176 * @param delay Delay before submitting the work item (in milliseconds).
177 *
178 * @retval 0 Work item countdown started.
179 * @retval -EINPROGRESS Work item is already pending.
180 * @retval -EINVAL Work item is being processed or has completed its work.
181 * @retval -EADDRINUSE Work item is pending on a different workqueue.
182 */
183 int k_delayed_work_submit(struct k_delayed_work *work, int32_t delay);
184
185 int k_delayed_work_submit_periodic(struct k_delayed_work *work, int32_t period);
186
187 /**
188 * @brief Get time remaining before a delayed work gets scheduled.
189 *
190 * This routine computes the (approximate) time remaining before a
191 * delayed work gets executed. If the delayed work is not waiting to be
192 * scheduled, it returns zero.
193 *
194 * @param work Delayed work item.
195 *
196 * @return Remaining time (in milliseconds).
197 */
198 int32_t k_delayed_work_remaining_get(struct k_delayed_work *work);
199
200 /**
201 * @brief Submit a work item to the system workqueue.
202 *
203 * This routine submits work item @a work to be processed by the system
204 * workqueue. If the work item is already pending in the workqueue's queue
205 * as a result of an earlier submission, this routine has no effect on the
206 * work item. If the work item has already been processed, or is currently
207 * being processed, its work is considered complete and the work item can be
208 * resubmitted.
209 *
210 * @warning
211 * Work items submitted to the system workqueue should avoid using handlers
212 * that block or yield since this may prevent the system workqueue from
213 * processing other work items in a timely manner.
214 *
215 * @note Can be called by ISRs.
216 *
217 * @param work Address of work item.
218 *
219 * @return N/A
220 */
k_work_submit(struct k_work * work)221 static inline void k_work_submit(struct k_work *work)
222 {
223 if (work && work->handler) {
224 work->handler(work);
225 }
226 }
227
228 /**
229 * @brief Initialize a work item.
230 *
231 * This routine initializes a workqueue work item, prior to its first use.
232 *
233 * @param work Address of work item.
234 * @param handler Function to invoke each time work item is processed.
235 *
236 * @return N/A
237 */
k_work_init(struct k_work * work,k_work_handler_t handler)238 static inline void k_work_init(struct k_work *work, k_work_handler_t handler)
239 {
240 work->handler = handler;
241 }
242
243 int k_delayed_work_cancel(struct k_delayed_work *work);
244
245 int k_delayed_work_free(struct k_delayed_work *work);
246
247 int k_delayed_work_init(struct k_delayed_work *work, k_work_handler_t handler);
248
249 /**
250 * @brief Get system uptime.
251 *
252 * This routine returns the elapsed time since the system booted,
253 * in milliseconds.
254 *
255 * @return Current uptime.
256 */
257 int64_t k_uptime_get(void);
258
259 void bt_mesh_timer_init(void);
260 void bt_mesh_timer_deinit(void);
261
262 #ifdef __cplusplus
263 }
264 #endif
265
266 #endif /* _BLE_MESH_TIMER_H_ */
267