ztimer.h
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: 2018 Kaspar Schleiser <kaspar@schleiser.de>
3  * SPDX-License-Identifier: LGPL-2.1-only
4  */
5 
6 #pragma once
7 
262 #include <stdint.h>
263 
264 #include "mbox.h"
265 #include "msg.h"
266 #include "mutex.h"
267 #include "rmutex.h"
268 #include "sched.h"
269 
270 #ifdef __cplusplus
271 extern "C" {
272 #endif
273 
277 #define ZTIMER_CLOCK_NO_REQUIRED_PM_MODE (UINT8_MAX)
278 
282 typedef struct ztimer_base ztimer_base_t;
283 
287 typedef struct ztimer_clock ztimer_clock_t;
288 
292 typedef void (*ztimer_callback_t)(void *arg);
293 
297 struct ztimer_base {
299  uint32_t offset;
300 };
301 
308 typedef uint32_t ztimer_now_t;
309 
316 typedef struct {
319  void *arg;
320 } ztimer_t;
321 
329 typedef struct {
335  void (*set)(ztimer_clock_t *clock, uint32_t val);
336 
341  uint32_t (*now)(ztimer_clock_t *clock);
342 
347  void (*cancel)(ztimer_clock_t *clock);
348 
349 #if MODULE_ZTIMER_ONDEMAND || DOXYGEN
354  void (*start)(ztimer_clock_t *clock);
355 
360  void (*stop)(ztimer_clock_t *clock);
361 #endif
362 } ztimer_ops_t;
363 
367 struct ztimer_clock {
369  const ztimer_ops_t *ops;
371  uint16_t adjust_set;
372  uint16_t adjust_sleep;
374 #if MODULE_ZTIMER_ONDEMAND || DOXYGEN
378  uint16_t users;
379 #endif
380 #if MODULE_ZTIMER_EXTEND || DOXYGEN
381  /* values used for checkpointed intervals and 32bit extension */
382  uint32_t max_value;
383  uint32_t lower_last;
385 #endif
386 #if MODULE_PM_LAYERED && !MODULE_ZTIMER_ONDEMAND || DOXYGEN
387  uint8_t block_pm_mode;
389 #endif
390 };
391 
399 
400 /* User API */
412 #if MODULE_ZTIMER_ONDEMAND || DOXYGEN
414 #else
415 static inline bool ztimer_acquire(ztimer_clock_t *clock)
416 {
417  (void)clock;
418  return false;
419 }
420 #endif
421 
432 #if MODULE_ZTIMER_ONDEMAND || DOXYGEN
434 #else
435 static inline bool ztimer_release(ztimer_clock_t *clock)
436 {
437  (void)clock;
438  return false;
439 }
440 #endif
441 
458 uint32_t ztimer_set(ztimer_clock_t *clock, ztimer_t *timer, uint32_t val);
459 
469 unsigned ztimer_is_set(const ztimer_clock_t *clock, const ztimer_t *timer);
470 
488 bool ztimer_remove(ztimer_clock_t *clock, ztimer_t *timer);
489 
505 void ztimer_set_msg(ztimer_clock_t *clock, ztimer_t *timer, uint32_t offset,
506  msg_t *msg, kernel_pid_t target_pid);
507 
526  uint32_t timeout);
527 
528 /* created with dist/tools/define2u16.py */
529 #define MSG_ZTIMER 0xc83e
545 int ztimer_mbox_get_timeout(ztimer_clock_t *clock, mbox_t *mbox, msg_t *msg, uint32_t timeout);
546 
556 
567 
681 {
682 #if MODULE_ZTIMER_ONDEMAND && DEVELHELP
684 #endif
685 
686 #if MODULE_ZTIMER_EXTEND
687  if (clock->max_value < UINT32_MAX) {
688 #else
689  if (0) {
690 #endif
691  return _ztimer_now_extend(clock);
692  }
693  else {
694  return clock->ops->now(clock);
695  }
696 }
697 
720 void ztimer_periodic_wakeup(ztimer_clock_t *clock, uint32_t *last_wakeup,
721  uint32_t period);
722 
729 void ztimer_sleep(ztimer_clock_t *clock, uint32_t duration);
730 
739 static inline void ztimer_spin(ztimer_clock_t *clock, uint32_t duration)
740 {
741  ztimer_acquire(clock);
742  uint32_t end = ztimer_now(clock) + duration;
743 
744  /* Rely on integer overflow. `end - now` will be smaller than `duration`,
745  * counting down, until it underflows to UINT32_MAX. Loop ends then. */
746  while ((end - ztimer_now(clock)) <= duration) {}
747  ztimer_release(clock);
748 }
749 
761 void ztimer_set_wakeup(ztimer_clock_t *clock, ztimer_t *timer, uint32_t offset,
762  kernel_pid_t pid);
763 
775  uint32_t timeout);
776 
788  uint32_t timeout, mutex_t *mutex);
789 
801  uint32_t timeout);
802 
814  uint32_t timeout);
815 
819 void ztimer_init(void);
820 
821 #if defined(MODULE_ZTIMER_EXTEND) || defined(DOXYGEN)
832 static inline void ztimer_init_extend(ztimer_clock_t *clock)
833 {
834  if (clock->max_value < UINT32_MAX) {
835  clock->ops->set(clock, clock->max_value >> 1);
836  }
837 }
838 #endif /* MODULE_ZTIMER_EXTEND */
839 
840 /* default ztimer virtual devices */
844 extern ztimer_clock_t *const ZTIMER_USEC;
845 
849 extern ztimer_clock_t *const ZTIMER_MSEC;
850 
854 extern ztimer_clock_t *const ZTIMER_SEC;
855 
870 extern ztimer_clock_t *const ZTIMER_USEC_BASE;
871 
889 extern ztimer_clock_t *const ZTIMER_MSEC_BASE;
890 
891 #ifdef __cplusplus
892 }
893 #endif
894 
int16_t kernel_pid_t
Unique process identifier.
Definition: sched.h:135
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:292
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:739
bool ztimer_acquire(ztimer_clock_t *clock)
Acquire a clock.
uint32_t ztimer_now_t
type for ztimer_now() result
Definition: ztimer.h:308
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)
static void ztimer_init_extend(ztimer_clock_t *clock)
Initialize possible ztimer extension intermediate timer.
Definition: ztimer.h:832
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:37
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
Minimum information for each timer.
Definition: ztimer.h:297
uint32_t offset
offset from last timer in list
Definition: ztimer.h:299
ztimer_base_t * next
next timer in list
Definition: ztimer.h:298
ztimer device structure
Definition: ztimer.h:367
uint16_t adjust_sleep
will be subtracted on every sleep(), in addition to adjust_set
Definition: ztimer.h:372
uint32_t lower_last
timer value at last now() call
Definition: ztimer.h:383
uint32_t max_value
maximum relative timer value
Definition: ztimer.h:382
ztimer_now_t checkpoint
cumulated time at last now() call
Definition: ztimer.h:384
ztimer_base_t * last
last timer in queue, for _is_set()
Definition: ztimer.h:370
uint16_t users
user count of this clock
Definition: ztimer.h:378
ztimer_base_t list
list of active timers
Definition: ztimer.h:368
uint16_t adjust_clock_start
will be subtracted on every set(), if the underlying periph is in stopped state
Definition: ztimer.h:375
uint16_t adjust_set
will be subtracted on every set()
Definition: ztimer.h:371
const ztimer_ops_t * ops
pointer to methods structure
Definition: ztimer.h:369
uint8_t block_pm_mode
min.
Definition: ztimer.h:387
ztimer backend method structure
Definition: ztimer.h:329
uint32_t(* now)(ztimer_clock_t *clock)
Get the current count of the timer.
Definition: ztimer.h:341
void(* set)(ztimer_clock_t *clock, uint32_t val)
Set a new timer target.
Definition: ztimer.h:335
ztimer structure
Definition: ztimer.h:316
ztimer_callback_t callback
timer callback function pointer
Definition: ztimer.h:318
void * arg
timer callback argument
Definition: ztimer.h:319
ztimer_base_t base
clock list entry
Definition: ztimer.h:317