xtimer_compat.h
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: 2019 Kaspar Schleiser <kaspar@schleiser.de>
3  * SPDX-License-Identifier: LGPL-2.1-only
4  */
5 
6 #pragma once
7 
20 #include <assert.h>
21 #include <stdbool.h>
22 #include <stdint.h>
23 
24 /* make sure to overwrite potentially conflicting XTIMER_WIDTH definition from
25  * board.h by eagerly including it */
26 #include "board.h"
27 #include "timex.h"
28 #ifdef MODULE_CORE_MSG
29 #include "msg.h"
30 #endif /* MODULE_CORE_MSG */
31 #include "mutex.h"
32 #include "sched.h"
33 
34 #include "ztimer.h"
35 
36 #ifdef __cplusplus
37 extern "C" {
38 #endif
39 
40 /* the xtimer API is documented elsewhere. This is just an (incomplete) wrapper,
41  * so skip doxygen.
42  */
43 #ifndef DOXYGEN
44 
45 /* ztimer clocks with width lower than 32 bit get extended to 32 bit in software
46  * via ztimer_extend. So no matter what was defined elsewhere, we overwrite it
47  */
48 #ifdef XTIMER_WIDTH
49 #undef XTIMER_WIDTH
50 #endif
51 
52 #define XTIMER_WIDTH (32)
53 #define XTIMER_MASK (0)
54 
60 #ifndef XTIMER_BACKOFF
61 #define XTIMER_BACKOFF 1
62 #endif
63 
64 typedef ztimer_t xtimer_t;
65 typedef uint32_t xtimer_ticks32_t;
66 typedef uint64_t xtimer_ticks64_t;
67 
68 static inline void xtimer_init(void)
69 {
70  ztimer_init();
71 }
72 
73 static inline bool xtimer_is_set(const xtimer_t *timer)
74 {
75  return ztimer_is_set(ZTIMER_USEC, timer);
76 }
77 
78 static inline xtimer_ticks32_t xtimer_ticks(uint32_t ticks)
79 {
80  return ticks;
81 }
82 
83 static inline uint32_t xtimer_usec_from_ticks(xtimer_ticks32_t ticks)
84 {
85  return ticks;
86 }
87 
88 static inline uint64_t xtimer_usec_from_ticks64(xtimer_ticks64_t ticks)
89 {
90  return ticks;
91 }
92 
93 static inline xtimer_ticks32_t xtimer_ticks_from_usec(uint32_t usec)
94 {
95  return usec;
96 }
97 
98 static inline xtimer_ticks64_t xtimer_ticks_from_usec64(uint64_t usec)
99 {
100  return usec;
101 }
102 
103 static inline xtimer_ticks32_t xtimer_now(void)
104 {
105  return ztimer_now(ZTIMER_USEC);
106 }
107 
108 static inline uint32_t xtimer_now_usec(void)
109 {
110  return ztimer_now(ZTIMER_USEC);
111 }
112 
113 static inline void _ztimer_sleep_scale(ztimer_clock_t *clock, uint32_t time,
114  uint32_t scale)
115 {
116  const uint32_t max_sleep = UINT32_MAX / scale;
117 
118  while (time > max_sleep) {
119  ztimer_sleep(clock, max_sleep * scale);
120  time -= max_sleep;
121  }
122 
123  ztimer_sleep(clock, time * scale);
124 }
125 
126 static inline void xtimer_sleep(uint32_t seconds)
127 {
128  /* TODO: use ZTIMER_SEC */
129  if (IS_ACTIVE(MODULE_ZTIMER_MSEC)) {
130  _ztimer_sleep_scale(ZTIMER_MSEC, seconds, MS_PER_SEC);
131  }
132  else {
133  _ztimer_sleep_scale(ZTIMER_USEC, seconds, US_PER_SEC);
134  }
135 }
136 
137 static inline void xtimer_msleep(uint32_t milliseconds)
138 {
139  if (IS_ACTIVE(MODULE_ZTIMER_MSEC)) {
140  ztimer_sleep(ZTIMER_MSEC, milliseconds);
141  }
142  else {
143  _ztimer_sleep_scale(ZTIMER_USEC, milliseconds, US_PER_MS);
144  }
145 }
146 
147 static inline void xtimer_usleep(uint32_t microseconds)
148 {
149  ztimer_sleep(ZTIMER_USEC, microseconds);
150 }
151 
152 static inline void xtimer_nanosleep(uint32_t nanoseconds)
153 {
154  ztimer_sleep(ZTIMER_USEC, nanoseconds / NS_PER_US);
155 }
156 
157 static inline void xtimer_tsleep32(xtimer_ticks32_t ticks)
158 {
160 }
161 
162 static inline void xtimer_tsleep64(xtimer_ticks64_t ticks)
163 {
164  const uint32_t max_sleep = UINT32_MAX;
165  uint64_t time = xtimer_usec_from_ticks64(ticks);
166 
167  while (time > max_sleep) {
168  xtimer_usleep(max_sleep);
169  time -= max_sleep;
170  }
171  xtimer_usleep(time);
172 }
173 
174 static inline void xtimer_set(xtimer_t *timer, uint32_t offset)
175 {
176  ztimer_set(ZTIMER_USEC, timer, offset);
177 }
178 
179 static inline void xtimer_remove(xtimer_t *timer)
180 {
181  ztimer_remove(ZTIMER_USEC, timer);
182 }
183 
184 static inline void xtimer_set_msg(xtimer_t *timer, uint32_t offset, msg_t *msg,
185  kernel_pid_t target_pid)
186 {
187  ztimer_set_msg(ZTIMER_USEC, timer, offset, msg, target_pid);
188 }
189 
190 static inline void xtimer_periodic_wakeup(xtimer_ticks32_t *last_wakeup,
191  uint32_t period)
192 {
193  ztimer_periodic_wakeup(ZTIMER_USEC, last_wakeup, period);
194 }
195 
196 static inline int xtimer_msg_receive_timeout(msg_t *msg, uint32_t timeout)
197 {
198  return ztimer_msg_receive_timeout(ZTIMER_USEC, msg, timeout);
199 }
200 
201 static inline void xtimer_set_wakeup(xtimer_t *timer, uint32_t offset,
202  kernel_pid_t pid)
203 {
204  ztimer_set_wakeup(ZTIMER_USEC, timer, offset, pid);
205 }
206 
207 static inline int xtimer_mutex_lock_timeout(mutex_t *mutex, uint64_t us)
208 {
209  assert(us <= UINT32_MAX);
210  if (ztimer_mutex_lock_timeout(ZTIMER_USEC, mutex, (uint32_t)us)) {
211  /* Impedance matching required: Convert -ECANCELED error code to -1: */
212  return -1;
213  }
214  return 0;
215 }
216 
217 static inline int xtimer_rmutex_lock_timeout(rmutex_t *rmutex, uint64_t us)
218 {
219  assert(us <= UINT32_MAX);
220  if (ztimer_rmutex_lock_timeout(ZTIMER_USEC, rmutex, us)) {
221  /* Impedance matching required: Convert -ECANCELED error code to -1: */
222  return -1;
223  }
224  return 0;
225 }
226 
227 static inline void xtimer_set_timeout_flag(xtimer_t *t, uint32_t timeout)
228 {
230 }
231 
232 static inline void xtimer_set_timeout_flag64(xtimer_t *t, uint64_t timeout)
233 {
234  assert(timeout <= UINT32_MAX);
235  xtimer_set_timeout_flag(t, timeout);
236 }
237 
238 static inline void xtimer_spin(xtimer_ticks32_t ticks)
239 {
241 }
242 
245 {
246  return a - b;
247 }
248 
251 {
252  return a - b;
253 }
254 
257 {
258  return (xtimer_ticks32_t)(a - b);
259 }
260 
261 static inline xtimer_ticks64_t xtimer_ticks64(uint64_t ticks)
262 {
263  return ticks;
264 }
265 
266 static inline bool xtimer_less(xtimer_ticks32_t a, xtimer_ticks32_t b)
267 {
268  return a < b;
269 }
270 
271 static inline bool xtimer_less64(xtimer_ticks64_t a, xtimer_ticks64_t b)
272 {
273  return a < b;
274 }
275 
276 /* unsupported due to using ztimer (32Bit):
277  * please use ztimer64_xtimer_compat if need
278 
279  xtimer_ticks64_t xtimer_now64(void);
280  uint64_t xtimer_now_usec64(void):
281  void xtimer_now_timex(timex_t *out)
282  void xtimer_set64(xtimer_t *timer, uint64_t offset_us);
283  void xtimer_set_wakeup64(xtimer_t *timer, uint64_t offset,
284  kernel_pid_t pid);
285  void xtimer_set_msg64(xtimer_t *timer, uint64_t offset,
286  msg_t *msg, kernel_pid_t target_pid);
287  int xtimer_msg_receive_timeout64(msg_t *msg, uint64_t timeout);
288  */
289 
290 #endif /* DOXYGEN */
291 
292 #ifdef __cplusplus
293 }
294 #endif
295 
POSIX.1-2008 compliant version of the assert macro.
#define assert(cond)
abort the program if assertion is false
Definition: assert.h:143
int16_t kernel_pid_t
Unique process identifier.
Definition: sched.h:135
#define US_PER_MS
The number of microseconds per millisecond.
Definition: time_units.h:86
#define US_PER_SEC
The number of microseconds per second.
Definition: time_units.h:81
#define MS_PER_SEC
The number of milliseconds per second.
Definition: time_units.h:71
#define NS_PER_US
The number of nanoseconds per microsecond.
Definition: time_units.h:96
void xtimer_set_timeout_flag64(xtimer_t *t, uint64_t timeout)
Set timeout thread flag after timeout.
static void xtimer_usleep(uint32_t microseconds)
Pause the execution of a thread for some microseconds.
static xtimer_ticks32_t xtimer_diff(xtimer_ticks32_t a, xtimer_ticks32_t b)
Compute difference between two xtimer time stamps.
static uint32_t xtimer_now_usec(void)
get the current system time in microseconds since start
static xtimer_ticks64_t xtimer_ticks_from_usec64(uint64_t usec)
Convert microseconds to xtimer ticks, 64 bit version.
void xtimer_remove(xtimer_t *timer)
remove a timer
static bool xtimer_less64(xtimer_ticks64_t a, xtimer_ticks64_t b)
Compare two xtimer time stamps, 64 bit version.
static void xtimer_tsleep32(xtimer_ticks32_t ticks)
Stop execution of a thread for some time, 32bit version.
static void xtimer_msleep(uint32_t milliseconds)
Pause the execution of a thread for some milliseconds.
static void xtimer_sleep(uint32_t seconds)
Pause the execution of a thread for some seconds.
static xtimer_ticks32_t xtimer_diff32_64(xtimer_ticks64_t a, xtimer_ticks64_t b)
Compute 32 bit difference between two 64 bit xtimer time stamps.
int xtimer_rmutex_lock_timeout(rmutex_t *rmutex, uint64_t us)
lock a rmutex but with timeout
static xtimer_ticks64_t xtimer_ticks64(uint64_t ticks)
Create an xtimer time stamp, 64 bit version.
static void xtimer_periodic_wakeup(xtimer_ticks32_t *last_wakeup, uint32_t period)
will cause the calling thread to be suspended until the absolute time (last_wakeup + period).
static void xtimer_set_msg(xtimer_t *timer, uint32_t offset, msg_t *msg, kernel_pid_t target_pid)
Set a timer that sends a message.
static bool xtimer_less(xtimer_ticks32_t a, xtimer_ticks32_t b)
Compare two xtimer time stamps.
static uint32_t xtimer_usec_from_ticks(xtimer_ticks32_t ticks)
Convert xtimer ticks to microseconds.
static xtimer_ticks64_t xtimer_diff64(xtimer_ticks64_t a, xtimer_ticks64_t b)
Compute difference between two xtimer time stamps, 64 bit version.
int xtimer_mutex_lock_timeout(mutex_t *mutex, uint64_t us)
lock a mutex but with timeout
static int xtimer_msg_receive_timeout(msg_t *msg, uint32_t timeout)
receive a message blocking but with timeout
void xtimer_set_timeout_flag(xtimer_t *t, uint32_t timeout)
Set timeout thread flag after timeout.
static void xtimer_tsleep64(xtimer_ticks64_t ticks)
Stop execution of a thread for some time, 64bit version.
static void xtimer_nanosleep(uint32_t nanoseconds)
Stop execution of a thread for some time.
static void xtimer_set_wakeup(xtimer_t *timer, uint32_t offset, kernel_pid_t pid)
Set a timer that wakes up a thread.
void xtimer_init(void)
xtimer initialization function
static void xtimer_spin(xtimer_ticks32_t ticks)
Stop execution of a thread for some time, blocking.
static void xtimer_set(xtimer_t *timer, uint32_t offset)
Set a timer to execute a callback at some time in the future.
static xtimer_ticks32_t xtimer_ticks_from_usec(uint32_t usec)
Convert microseconds to xtimer ticks.
struct xtimer xtimer_t
xtimer timer structure
static xtimer_ticks32_t xtimer_ticks(uint32_t ticks)
Create an xtimer time stamp.
static xtimer_ticks32_t xtimer_now(void)
get the current system time as 32bit time stamp value
static bool xtimer_is_set(const xtimer_t *timer)
state if an xtimer is currently set (waiting to be expired)
static uint64_t xtimer_usec_from_ticks64(xtimer_ticks64_t ticks)
Convert xtimer ticks to microseconds, 64 bit version.
void ztimer_init(void)
Initialize the board-specific default ztimer configuration.
void ztimer_periodic_wakeup(ztimer_clock_t *clock, uint32_t *last_wakeup, uint32_t period)
Suspend the calling thread until the time (last_wakeup + period)
void ztimer_set_wakeup(ztimer_clock_t *clock, ztimer_t *timer, uint32_t offset, kernel_pid_t pid)
Set a timer that wakes up a thread.
void ztimer_set_msg(ztimer_clock_t *clock, ztimer_t *timer, uint32_t offset, msg_t *msg, kernel_pid_t target_pid)
Post a message after a delay.
uint32_t ztimer_set(ztimer_clock_t *clock, ztimer_t *timer, uint32_t val)
Set a timer on a clock.
ztimer_clock_t *const ZTIMER_USEC
Default ztimer microsecond clock.
static void ztimer_spin(ztimer_clock_t *clock, uint32_t duration)
Busy-wait specified duration.
Definition: ztimer.h:739
static ztimer_now_t ztimer_now(ztimer_clock_t *clock)
Get the current time from a clock.
Definition: ztimer.h:680
int ztimer_msg_receive_timeout(ztimer_clock_t *clock, msg_t *msg, uint32_t timeout)
receive a message (blocking, with timeout)
unsigned ztimer_is_set(const ztimer_clock_t *clock, const ztimer_t *timer)
Check if a timer is currently active.
int ztimer_rmutex_lock_timeout(ztimer_clock_t *clock, rmutex_t *rmutex, uint32_t timeout)
Try to lock the given rmutex, but give up after timeout.
void ztimer_sleep(ztimer_clock_t *clock, uint32_t duration)
Put the calling thread to sleep for the specified number of ticks.
bool ztimer_remove(ztimer_clock_t *clock, ztimer_t *timer)
Remove a timer from a clock.
void ztimer_set_timeout_flag(ztimer_clock_t *clock, ztimer_t *timer, uint32_t timeout)
Set timeout thread flag after timeout.
int ztimer_mutex_lock_timeout(ztimer_clock_t *clock, mutex_t *mutex, uint32_t timeout)
Try to lock the given mutex, but give up after timeout.
ztimer_clock_t *const ZTIMER_MSEC
Default ztimer millisecond clock.
#define IS_ACTIVE(macro)
Allows to verify a macro definition outside the preprocessor.
Definition: modules.h:56
Mutex for thread synchronization.
Scheduler API definition.
Describes a message object which can be sent between threads.
Definition: msg.h:192
Mutex structure.
Definition: mutex.h:36
Mutex structure.
Definition: rmutex.h:34
xtimer timestamp (32 bit)
Definition: xtimer.h:88
xtimer timestamp (64 bit)
Definition: xtimer.h:79
xtimer timer structure
Definition: xtimer.h:100
ztimer device structure
Definition: ztimer.h:367
ztimer structure
Definition: ztimer.h:316
Utility library for comparing and computing timestamps.
ztimer API