xtimer_compat.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2019 Kaspar Schleiser <kaspar@schleiser.de>
3  *
4  * This file is subject to the terms and conditions of the GNU Lesser
5  * General Public License v2.1. See the file LICENSE in the top level
6  * directory for more details.
7  */
8 
20 #ifndef ZTIMER_XTIMER_COMPAT_H
21 #define ZTIMER_XTIMER_COMPAT_H
22 
23 #include <assert.h>
24 #include <stdbool.h>
25 #include <stdint.h>
26 
27 /* make sure to overwrite potentially conflicting XTIMER_WIDTH definition from
28  * board.h by eagerly including it */
29 #include "board.h"
30 #include "timex.h"
31 #ifdef MODULE_CORE_MSG
32 #include "msg.h"
33 #endif /* MODULE_CORE_MSG */
34 #include "mutex.h"
35 #include "sched.h"
36 
37 #include "ztimer.h"
38 
39 #ifdef __cplusplus
40 extern "C" {
41 #endif
42 
43 /* the xtimer API is documented elsewhere. This is just an (incomplete) wrapper,
44  * so skip doxygen.
45  */
46 #ifndef DOXYGEN
47 
48 /* ztimer clocks with width lower than 32 bit get extended to 32 bit in software
49  * via ztimer_extend. So no matter what was defined elsewhere, we overwrite it
50  */
51 #ifdef XTIMER_WIDTH
52 #undef XTIMER_WIDTH
53 #endif
54 
55 #define XTIMER_WIDTH (32)
56 #define XTIMER_MASK (0)
57 
63 #ifndef XTIMER_BACKOFF
64 #define XTIMER_BACKOFF 1
65 #endif
66 
67 typedef ztimer_t xtimer_t;
68 typedef uint32_t xtimer_ticks32_t;
69 typedef uint64_t xtimer_ticks64_t;
70 
71 static inline void xtimer_init(void)
72 {
73  ztimer_init();
74 }
75 
76 static inline bool xtimer_is_set(const xtimer_t *timer)
77 {
78  return ztimer_is_set(ZTIMER_USEC, timer);
79 }
80 
81 static inline xtimer_ticks32_t xtimer_ticks(uint32_t ticks)
82 {
83  return ticks;
84 }
85 
86 static inline uint32_t xtimer_usec_from_ticks(xtimer_ticks32_t ticks)
87 {
88  return ticks;
89 }
90 
91 static inline uint64_t xtimer_usec_from_ticks64(xtimer_ticks64_t ticks)
92 {
93  return ticks;
94 }
95 
96 static inline xtimer_ticks32_t xtimer_ticks_from_usec(uint32_t usec)
97 {
98  return usec;
99 }
100 
101 static inline xtimer_ticks64_t xtimer_ticks_from_usec64(uint64_t usec)
102 {
103  return usec;
104 }
105 
106 static inline xtimer_ticks32_t xtimer_now(void)
107 {
108  return ztimer_now(ZTIMER_USEC);
109 }
110 
111 static inline uint32_t xtimer_now_usec(void)
112 {
113  return ztimer_now(ZTIMER_USEC);
114 }
115 
116 static inline void _ztimer_sleep_scale(ztimer_clock_t *clock, uint32_t time,
117  uint32_t scale)
118 {
119  const uint32_t max_sleep = UINT32_MAX / scale;
120 
121  while (time > max_sleep) {
122  ztimer_sleep(clock, max_sleep * scale);
123  time -= max_sleep;
124  }
125 
126  ztimer_sleep(clock, time * scale);
127 }
128 
129 static inline void xtimer_sleep(uint32_t seconds)
130 {
131  /* TODO: use ZTIMER_SEC */
132  if (IS_ACTIVE(MODULE_ZTIMER_MSEC)) {
133  _ztimer_sleep_scale(ZTIMER_MSEC, seconds, MS_PER_SEC);
134  }
135  else {
136  _ztimer_sleep_scale(ZTIMER_USEC, seconds, US_PER_SEC);
137  }
138 }
139 
140 static inline void xtimer_msleep(uint32_t milliseconds)
141 {
142  if (IS_ACTIVE(MODULE_ZTIMER_MSEC)) {
143  ztimer_sleep(ZTIMER_MSEC, milliseconds);
144  }
145  else {
146  _ztimer_sleep_scale(ZTIMER_USEC, milliseconds, US_PER_MS);
147  }
148 }
149 
150 static inline void xtimer_usleep(uint32_t microseconds)
151 {
152  ztimer_sleep(ZTIMER_USEC, microseconds);
153 }
154 
155 static inline void xtimer_nanosleep(uint32_t nanoseconds)
156 {
157  ztimer_sleep(ZTIMER_USEC, nanoseconds / NS_PER_US);
158 }
159 
160 static inline void xtimer_tsleep32(xtimer_ticks32_t ticks)
161 {
163 }
164 
165 static inline void xtimer_tsleep64(xtimer_ticks64_t ticks)
166 {
167  const uint32_t max_sleep = UINT32_MAX;
168  uint64_t time = xtimer_usec_from_ticks64(ticks);
169 
170  while (time > max_sleep) {
171  xtimer_usleep(max_sleep);
172  time -= max_sleep;
173  }
174  xtimer_usleep(time);
175 }
176 
177 static inline void xtimer_set(xtimer_t *timer, uint32_t offset)
178 {
179  ztimer_set(ZTIMER_USEC, timer, offset);
180 }
181 
182 static inline void xtimer_remove(xtimer_t *timer)
183 {
184  ztimer_remove(ZTIMER_USEC, timer);
185 }
186 
187 static inline void xtimer_set_msg(xtimer_t *timer, uint32_t offset, msg_t *msg,
188  kernel_pid_t target_pid)
189 {
190  ztimer_set_msg(ZTIMER_USEC, timer, offset, msg, target_pid);
191 }
192 
193 static inline void xtimer_periodic_wakeup(xtimer_ticks32_t *last_wakeup,
194  uint32_t period)
195 {
196  ztimer_periodic_wakeup(ZTIMER_USEC, last_wakeup, period);
197 }
198 
199 static inline int xtimer_msg_receive_timeout(msg_t *msg, uint32_t timeout)
200 {
201  return ztimer_msg_receive_timeout(ZTIMER_USEC, msg, timeout);
202 }
203 
204 static inline void xtimer_set_wakeup(xtimer_t *timer, uint32_t offset,
205  kernel_pid_t pid)
206 {
207  ztimer_set_wakeup(ZTIMER_USEC, timer, offset, pid);
208 }
209 
210 static inline int xtimer_mutex_lock_timeout(mutex_t *mutex, uint64_t us)
211 {
212  assert(us <= UINT32_MAX);
213  if (ztimer_mutex_lock_timeout(ZTIMER_USEC, mutex, (uint32_t)us)) {
214  /* Impedance matching required: Convert -ECANCELED error code to -1: */
215  return -1;
216  }
217  return 0;
218 }
219 
220 static inline int xtimer_rmutex_lock_timeout(rmutex_t *rmutex, uint64_t us)
221 {
222  assert(us <= UINT32_MAX);
223  if (ztimer_rmutex_lock_timeout(ZTIMER_USEC, rmutex, us)) {
224  /* Impedance matching required: Convert -ECANCELED error code to -1: */
225  return -1;
226  }
227  return 0;
228 }
229 
230 static inline void xtimer_set_timeout_flag(xtimer_t *t, uint32_t timeout)
231 {
233 }
234 
235 static inline void xtimer_set_timeout_flag64(xtimer_t *t, uint64_t timeout)
236 {
237  assert(timeout <= UINT32_MAX);
238  xtimer_set_timeout_flag(t, timeout);
239 }
240 
241 static inline void xtimer_spin(xtimer_ticks32_t ticks)
242 {
244 }
245 
248 {
249  return a - b;
250 }
251 
254 {
255  return a - b;
256 }
257 
260 {
261  return (xtimer_ticks32_t)(a - b);
262 }
263 
264 static inline xtimer_ticks64_t xtimer_ticks64(uint64_t ticks)
265 {
266  return ticks;
267 }
268 
269 static inline bool xtimer_less(xtimer_ticks32_t a, xtimer_ticks32_t b)
270 {
271  return a < b;
272 }
273 
274 static inline bool xtimer_less64(xtimer_ticks64_t a, xtimer_ticks64_t b)
275 {
276  return a < b;
277 }
278 
279 /* unsupported due to using ztimer (32Bit):
280  * please use ztimer64_xtimer_compat if need
281 
282  xtimer_ticks64_t xtimer_now64(void);
283  uint64_t xtimer_now_usec64(void):
284  void xtimer_now_timex(timex_t *out)
285  void xtimer_set64(xtimer_t *timer, uint64_t offset_us);
286  void xtimer_set_wakeup64(xtimer_t *timer, uint64_t offset,
287  kernel_pid_t pid);
288  void xtimer_set_msg64(xtimer_t *timer, uint64_t offset,
289  msg_t *msg, kernel_pid_t target_pid);
290  int xtimer_msg_receive_timeout64(msg_t *msg, uint64_t timeout);
291  */
292 
293 #endif /* DOXYGEN */
294 
295 #ifdef __cplusplus
296 }
297 #endif
298 
300 #endif /* ZTIMER_XTIMER_COMPAT_H */
POSIX.1-2008 compliant version of the assert macro.
#define assert(cond)
abort the program if assertion is false
Definition: assert.h:136
int16_t kernel_pid_t
Unique process identifier.
Definition: sched.h:139
#define US_PER_MS
The number of microseconds per millisecond.
Definition: time_units.h:90
#define US_PER_SEC
The number of microseconds per second.
Definition: time_units.h:85
#define MS_PER_SEC
The number of milliseconds per second.
Definition: time_units.h:75
#define NS_PER_US
The number of nanoseconds per microsecond.
Definition: time_units.h:100
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:742
static ztimer_now_t ztimer_now(ztimer_clock_t *clock)
Get the current time from a clock.
Definition: ztimer.h:683
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:60
Mutex for thread synchronization.
Scheduler API definition.
Describes a message object which can be sent between threads.
Definition: msg.h:196
Mutex structure.
Definition: mutex.h:146
Mutex structure.
Definition: rmutex.h:38
xtimer timestamp (32 bit)
Definition: xtimer.h:85
xtimer timestamp (64 bit)
Definition: xtimer.h:76
xtimer timer structure
Definition: xtimer.h:97
ztimer device structure
Definition: ztimer.h:370
ztimer structure
Definition: ztimer.h:319
Utility library for comparing and computing timestamps.
ztimer API