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  */
262 #ifndef ZTIMER_H
263 #define ZTIMER_H
264 
265 #include <stdint.h>
266 
267 #include "mbox.h"
268 #include "msg.h"
269 #include "mutex.h"
270 #include "rmutex.h"
271 #include "sched.h"
272 
273 #ifdef __cplusplus
274 extern "C" {
275 #endif
276 
280 #define ZTIMER_CLOCK_NO_REQUIRED_PM_MODE (UINT8_MAX)
281 
285 typedef struct ztimer_base ztimer_base_t;
286 
290 typedef struct ztimer_clock ztimer_clock_t;
291 
295 typedef void (*ztimer_callback_t)(void *arg);
296 
300 struct ztimer_base {
302  uint32_t offset;
303 };
304 
311 typedef uint32_t ztimer_now_t;
312 
319 typedef struct {
322  void *arg;
323 } ztimer_t;
324 
332 typedef struct {
338  void (*set)(ztimer_clock_t *clock, uint32_t val);
339 
344  uint32_t (*now)(ztimer_clock_t *clock);
345 
350  void (*cancel)(ztimer_clock_t *clock);
351 
352 #if MODULE_ZTIMER_ONDEMAND || DOXYGEN
357  void (*start)(ztimer_clock_t *clock);
358 
363  void (*stop)(ztimer_clock_t *clock);
364 #endif
365 } ztimer_ops_t;
366 
370 struct ztimer_clock {
372  const ztimer_ops_t *ops;
374  uint16_t adjust_set;
375  uint16_t adjust_sleep;
377 #if MODULE_ZTIMER_ONDEMAND || DOXYGEN
381  uint16_t users;
382 #endif
383 #if MODULE_ZTIMER_EXTEND || DOXYGEN
384  /* values used for checkpointed intervals and 32bit extension */
385  uint32_t max_value;
386  uint32_t lower_last;
388 #endif
389 #if MODULE_PM_LAYERED && !MODULE_ZTIMER_ONDEMAND || DOXYGEN
390  uint8_t block_pm_mode;
392 #endif
393 };
394 
402 
403 /* User API */
415 #if MODULE_ZTIMER_ONDEMAND || DOXYGEN
417 #else
418 static inline bool ztimer_acquire(ztimer_clock_t *clock)
419 {
420  (void)clock;
421  return false;
422 }
423 #endif
424 
435 #if MODULE_ZTIMER_ONDEMAND || DOXYGEN
437 #else
438 static inline bool ztimer_release(ztimer_clock_t *clock)
439 {
440  (void)clock;
441  return false;
442 }
443 #endif
444 
461 uint32_t ztimer_set(ztimer_clock_t *clock, ztimer_t *timer, uint32_t val);
462 
472 unsigned ztimer_is_set(const ztimer_clock_t *clock, const ztimer_t *timer);
473 
491 bool ztimer_remove(ztimer_clock_t *clock, ztimer_t *timer);
492 
508 void ztimer_set_msg(ztimer_clock_t *clock, ztimer_t *timer, uint32_t offset,
509  msg_t *msg, kernel_pid_t target_pid);
510 
529  uint32_t timeout);
530 
531 /* created with dist/tools/define2u16.py */
532 #define MSG_ZTIMER 0xc83e
548 int ztimer_mbox_get_timeout(ztimer_clock_t *clock, mbox_t *mbox, msg_t *msg, uint32_t timeout);
549 
559 
570 
684 {
685 #if MODULE_ZTIMER_ONDEMAND && DEVELHELP
687 #endif
688 
689 #if MODULE_ZTIMER_EXTEND
690  if (clock->max_value < UINT32_MAX) {
691 #else
692  if (0) {
693 #endif
694  return _ztimer_now_extend(clock);
695  }
696  else {
697  return clock->ops->now(clock);
698  }
699 }
700 
723 void ztimer_periodic_wakeup(ztimer_clock_t *clock, uint32_t *last_wakeup,
724  uint32_t period);
725 
732 void ztimer_sleep(ztimer_clock_t *clock, uint32_t duration);
733 
742 static inline void ztimer_spin(ztimer_clock_t *clock, uint32_t duration)
743 {
744  ztimer_acquire(clock);
745  uint32_t end = ztimer_now(clock) + duration;
746 
747  /* Rely on integer overflow. `end - now` will be smaller than `duration`,
748  * counting down, until it underflows to UINT32_MAX. Loop ends then. */
749  while ((end - ztimer_now(clock)) <= duration) {}
750  ztimer_release(clock);
751 }
752 
764 void ztimer_set_wakeup(ztimer_clock_t *clock, ztimer_t *timer, uint32_t offset,
765  kernel_pid_t pid);
766 
778  uint32_t timeout);
779 
791  uint32_t timeout, mutex_t *mutex);
792 
804  uint32_t timeout);
805 
817  uint32_t timeout);
818 
822 void ztimer_init(void);
823 
824 #if defined(MODULE_ZTIMER_EXTEND) || defined(DOXYGEN)
835 static inline void ztimer_init_extend(ztimer_clock_t *clock)
836 {
837  if (clock->max_value < UINT32_MAX) {
838  clock->ops->set(clock, clock->max_value >> 1);
839  }
840 }
841 #endif /* MODULE_ZTIMER_EXTEND */
842 
843 /* default ztimer virtual devices */
847 extern ztimer_clock_t *const ZTIMER_USEC;
848 
852 extern ztimer_clock_t *const ZTIMER_MSEC;
853 
857 extern ztimer_clock_t *const ZTIMER_SEC;
858 
873 extern ztimer_clock_t *const ZTIMER_USEC_BASE;
874 
892 extern ztimer_clock_t *const ZTIMER_MSEC_BASE;
893 
894 #ifdef __cplusplus
895 }
896 #endif
897 
898 #endif /* ZTIMER_H */
int16_t kernel_pid_t
Unique process identifier.
Definition: sched.h:139
void ztimer_init(void)
Initialize the board-specific default ztimer configuration.
bool ztimer_release(ztimer_clock_t *clock)
Release a clock.
void(* ztimer_callback_t)(void *arg)
Type of callbacks in timers.
Definition: ztimer.h:295
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.
ztimer_clock_t *const ZTIMER_SEC
Default ztimer second clock.
int ztimer_mbox_get_timeout(ztimer_clock_t *clock, mbox_t *mbox, msg_t *msg, uint32_t timeout)
Get message from mailbox, blocking with a timeout.
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_t *const ZTIMER_MSEC_BASE
Base ztimer for the millisecond clock (ZTIMER_MSEC)
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
bool ztimer_acquire(ztimer_clock_t *clock)
Acquire a clock.
uint32_t ztimer_now_t
type for ztimer_now() result
Definition: ztimer.h:311
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)
static void ztimer_init_extend(ztimer_clock_t *clock)
Initialize possible ztimer extension intermediate timer.
Definition: ztimer.h:835
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_handler(ztimer_clock_t *clock)
main ztimer callback handler
ztimer_now_t _ztimer_now_extend(ztimer_clock_t *clock)
ztimer_now() for extending timers
void ztimer_mutex_unlock(ztimer_clock_t *clock, ztimer_t *timer, uint32_t timeout, mutex_t *mutex)
Unlock mutex after timeout.
ztimer_clock_t *const ZTIMER_USEC_BASE
Base ztimer for the microsecond clock (ZTIMER_USEC)
void _ztimer_assert_clock_active(ztimer_clock_t *clock)
asserts the given clock to be active
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.
Mailbox API.
Mutex for thread synchronization.
time_point now()
Returns the current time saved in a time point.
Definition: chrono.hpp:104
Recursive Mutex for thread synchronization.
Scheduler API definition.
Mailbox struct definition.
Definition: mbox.h:41
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
Minimum information for each timer.
Definition: ztimer.h:300
uint32_t offset
offset from last timer in list
Definition: ztimer.h:302
ztimer_base_t * next
next timer in list
Definition: ztimer.h:301
ztimer device structure
Definition: ztimer.h:370
uint16_t adjust_sleep
will be subtracted on every sleep(), in addition to adjust_set
Definition: ztimer.h:375
uint32_t lower_last
timer value at last now() call
Definition: ztimer.h:386
uint32_t max_value
maximum relative timer value
Definition: ztimer.h:385
ztimer_now_t checkpoint
cumulated time at last now() call
Definition: ztimer.h:387
ztimer_base_t * last
last timer in queue, for _is_set()
Definition: ztimer.h:373
uint16_t users
user count of this clock
Definition: ztimer.h:381
ztimer_base_t list
list of active timers
Definition: ztimer.h:371
uint16_t adjust_clock_start
will be subtracted on every set(), if the underlying periph is in stopped state
Definition: ztimer.h:378
uint16_t adjust_set
will be subtracted on every set()
Definition: ztimer.h:374
const ztimer_ops_t * ops
pointer to methods structure
Definition: ztimer.h:372
uint8_t block_pm_mode
min.
Definition: ztimer.h:390
ztimer backend method structure
Definition: ztimer.h:332
uint32_t(* now)(ztimer_clock_t *clock)
Get the current count of the timer.
Definition: ztimer.h:344
void(* set)(ztimer_clock_t *clock, uint32_t val)
Set a new timer target.
Definition: ztimer.h:338
ztimer structure
Definition: ztimer.h:319
ztimer_callback_t callback
timer callback function pointer
Definition: ztimer.h:321
void * arg
timer callback argument
Definition: ztimer.h:322
ztimer_base_t base
clock list entry
Definition: ztimer.h:320