ztimer.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2018 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  */
232 #ifndef ZTIMER_H
233 #define ZTIMER_H
234 
235 #include <stdint.h>
236 
237 #include "sched.h"
238 #include "msg.h"
239 
240 #ifdef __cplusplus
241 extern "C" {
242 #endif
243 
247 #define ZTIMER_CLOCK_NO_REQUIRED_PM_MODE (UINT8_MAX)
248 
252 typedef struct ztimer_base ztimer_base_t;
253 
258 
262 struct ztimer_base {
264  uint32_t offset;
265 };
266 
267 #if MODULE_ZTIMER_NOW64
268 typedef uint64_t ztimer_now_t;
269 #else
270 typedef uint32_t ztimer_now_t;
271 #endif
272 
279 typedef struct {
281  void (*callback)(void *arg);
282  void *arg;
283 } ztimer_t;
284 
292 typedef struct {
296  void (*set)(ztimer_clock_t *clock, uint32_t val);
297 
301  uint32_t (*now)(ztimer_clock_t *clock);
302 
306  void (*cancel)(ztimer_clock_t *clock);
307 } ztimer_ops_t;
308 
312 struct ztimer_clock {
314  const ztimer_ops_t *ops;
316  uint16_t adjust_set;
317  uint16_t adjust_sleep;
319 #if MODULE_ZTIMER_EXTEND || MODULE_ZTIMER_NOW64 || DOXYGEN
320  /* values used for checkpointed intervals and 32bit extension */
321  uint32_t max_value;
322  uint32_t lower_last;
324 #endif
325 #if MODULE_PM_LAYERED || DOXYGEN
327 #endif
328 };
329 
333 void ztimer_handler(ztimer_clock_t *clock);
334 
335 /* User API */
349 void ztimer_set(ztimer_clock_t *clock, ztimer_t *timer, uint32_t val);
350 
362 void ztimer_remove(ztimer_clock_t *clock, ztimer_t *timer);
363 
379 void ztimer_set_msg(ztimer_clock_t *clock, ztimer_t *timer, uint32_t offset,
380  msg_t *msg, kernel_pid_t target_pid);
381 
400  uint32_t timeout);
401 
402  /* created with dist/tools/define2u16.py */
403 #define MSG_ZTIMER 0xc83e
413 ztimer_now_t _ztimer_now_extend(ztimer_clock_t *clock);
414 
423 {
424 #if MODULE_ZTIMER_NOW64
425  if (1) {
426 #elif MODULE_ZTIMER_EXTEND
427  if (clock->max_value < UINT32_MAX) {
428 #else
429  if (0) {
430 #endif
431  return _ztimer_now_extend(clock);
432  }
433  else {
434  return clock->ops->now(clock);
435  }
436 }
437 
456 void ztimer_periodic_wakeup(ztimer_clock_t *clock, uint32_t *last_wakeup,
457  uint32_t period);
458 
465 void ztimer_sleep(ztimer_clock_t *clock, uint32_t duration);
466 
475 static inline void ztimer_spin(ztimer_clock_t *clock, uint32_t duration) {
476  uint32_t end = ztimer_now(clock) + duration;
477 
478  /* Rely on integer overflow. `end - now` will be smaller than `duration`,
479  * counting down, until it underflows to UINT32_MAX. Loop ends then. */
480  while ((end - ztimer_now(clock)) <= duration) {}
481 }
482 
494 void ztimer_set_wakeup(ztimer_clock_t *clock, ztimer_t *timer, uint32_t offset,
495  kernel_pid_t pid);
496 
508  uint32_t timeout);
509 
518 
522 void ztimer_init(void);
523 
524 #if defined(MODULE_ZTIMER_EXTEND) || defined(DOXYGEN)
525 
535 static inline void ztimer_init_extend(ztimer_clock_t *clock)
536 {
537  if (clock->max_value < UINT32_MAX) {
538  clock->ops->set(clock, clock->max_value >> 1);
539  }
540 }
541 #endif /* MODULE_ZTIMER_EXTEND */
542 
543 /* default ztimer virtual devices */
547 extern ztimer_clock_t *const ZTIMER_USEC;
548 
552 extern ztimer_clock_t *const ZTIMER_MSEC;
553 
568 extern ztimer_clock_t *const ZTIMER_USEC_BASE;
569 
587 extern ztimer_clock_t *const ZTIMER_MSEC_BASE;
588 
589 #ifdef __cplusplus
590 }
591 #endif
592 
593 #endif /* ZTIMER_H */
594 
ztimer_remove
void ztimer_remove(ztimer_clock_t *clock, ztimer_t *timer)
Remove a timer from a clock.
kernel_pid_t
int16_t kernel_pid_t
Unique process identifier.
Definition: sched.h:125
ztimer_clock::adjust_sleep
uint16_t adjust_sleep
will be subtracted on every sleep(), in addition to adjust_set
Definition: ztimer.h:317
ztimer_base::offset
uint32_t offset
offset from last timer in list
Definition: ztimer.h:264
ztimer_clock::list
ztimer_base_t list
list of active timers
Definition: ztimer.h:313
ztimer_t
ztimer structure
Definition: ztimer.h:279
msg.h
Messaging API for inter process communication.
ztimer_clock::checkpoint
ztimer_now_t checkpoint
cumulated time at last now() call
Definition: ztimer.h:323
sched.h
Scheduler API definition.
ztimer_t::arg
void * arg
timer callback argument
Definition: ztimer.h:282
ztimer_base::next
ztimer_base_t * next
next timer in list
Definition: ztimer.h:263
ztimer_ops_t::now
uint32_t(* now)(ztimer_clock_t *clock)
Get the current count of the timer.
Definition: ztimer.h:301
ZTIMER_MSEC
ztimer_clock_t *const ZTIMER_MSEC
Default ztimer millisecond clock.
ztimer_sleep
void ztimer_sleep(ztimer_clock_t *clock, uint32_t duration)
Put the calling thread to sleep for the specified number of ticks.
ZTIMER_MSEC_BASE
ztimer_clock_t *const ZTIMER_MSEC_BASE
Base ztimer for the millisecond clock (ZTIMER_MSEC)
ztimer_set
void ztimer_set(ztimer_clock_t *clock, ztimer_t *timer, uint32_t val)
Set a timer on a clock.
ztimer_spin
static void ztimer_spin(ztimer_clock_t *clock, uint32_t duration)
Busy-wait specified duration.
Definition: ztimer.h:475
ZTIMER_USEC_BASE
ztimer_clock_t *const ZTIMER_USEC_BASE
Base ztimer for the microsecond clock (ZTIMER_USEC)
ztimer_handler
void ztimer_handler(ztimer_clock_t *clock)
main ztimer callback handler
ztimer_init_extend
static void ztimer_init_extend(ztimer_clock_t *clock)
Initialize possible ztimer extension intermediate timer.
Definition: ztimer.h:535
ztimer_clock
ztimer device structure
Definition: ztimer.h:312
ZTIMER_USEC
ztimer_clock_t *const ZTIMER_USEC
Default ztimer microsecond clock.
ztimer_clock::ops
const ztimer_ops_t * ops
pointer to methods structure
Definition: ztimer.h:314
ztimer_clock::required_pm_mode
uint8_t required_pm_mode
min.
Definition: ztimer.h:326
ztimer_clock::max_value
uint32_t max_value
maximum relative timer value
Definition: ztimer.h:321
_ztimer_now_extend
ztimer_now_t _ztimer_now_extend(ztimer_clock_t *clock)
ztimer_now() for extending timers
ztimer_msg_receive_timeout
int ztimer_msg_receive_timeout(ztimer_clock_t *clock, msg_t *msg, uint32_t timeout)
receive a message (blocking, with timeout)
ztimer_now_t
uint32_t ztimer_now_t
type for ztimer_now() result
Definition: ztimer.h:270
ztimer_clock::adjust_set
uint16_t adjust_set
will be subtracted on every set()
Definition: ztimer.h:316
ztimer_set_timeout_flag
void ztimer_set_timeout_flag(ztimer_clock_t *clock, ztimer_t *timer, uint32_t timeout)
Set timeout thread flag after timeout.
ztimer_periodic_wakeup
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)
ztimer_ops_t
ztimer backend method structure
Definition: ztimer.h:292
msg_t
Describes a message object which can be sent between threads.
Definition: msg.h:185
ztimer_update_head_offset
void ztimer_update_head_offset(ztimer_clock_t *clock)
Update ztimer clock head list offset.
ztimer_set_msg
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.
ztimer_clock::lower_last
uint32_t lower_last
timer value at last now() call
Definition: ztimer.h:322
ztimer_base
Minimum information for each timer.
Definition: ztimer.h:262
ztimer_now
static ztimer_now_t ztimer_now(ztimer_clock_t *clock)
Get the current time from a clock.
Definition: ztimer.h:422
ztimer_t::base
ztimer_base_t base
clock list entry
Definition: ztimer.h:280
ztimer_set_wakeup
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.
ztimer_init
void ztimer_init(void)
Initialize the board-specific default ztimer configuration.
ztimer_ops_t::set
void(* set)(ztimer_clock_t *clock, uint32_t val)
Set a new timer target.
Definition: ztimer.h:296
ztimer_clock::last
ztimer_base_t * last
last timer in queue, for _is_set()
Definition: ztimer.h:315