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 "sched.h"
268 #include "msg.h"
269 #include "mutex.h"
270 #include "rmutex.h"
271 
272 #ifdef __cplusplus
273 extern "C" {
274 #endif
275 
279 #define ZTIMER_CLOCK_NO_REQUIRED_PM_MODE (UINT8_MAX)
280 
284 typedef struct ztimer_base ztimer_base_t;
285 
289 typedef struct ztimer_clock ztimer_clock_t;
290 
294 struct ztimer_base {
296  uint32_t offset;
297 };
298 
299 #if MODULE_ZTIMER_NOW64
300 typedef uint64_t ztimer_now_t;
301 #else
302 typedef uint32_t ztimer_now_t;
303 #endif
304 
311 typedef struct {
313  void (*callback)(void *arg);
314  void *arg;
315 } ztimer_t;
316 
324 typedef struct {
330  void (*set)(ztimer_clock_t *clock, uint32_t val);
331 
336  uint32_t (*now)(ztimer_clock_t *clock);
337 
342  void (*cancel)(ztimer_clock_t *clock);
343 } ztimer_ops_t;
344 
348 struct ztimer_clock {
350  const ztimer_ops_t *ops;
352  uint16_t adjust_set;
353  uint16_t adjust_sleep;
355 #if MODULE_ZTIMER_EXTEND || MODULE_ZTIMER_NOW64 || DOXYGEN
356  /* values used for checkpointed intervals and 32bit extension */
357  uint32_t max_value;
358  uint32_t lower_last;
360 #endif
361 #if MODULE_PM_LAYERED || DOXYGEN
362  uint8_t block_pm_mode;
363 #endif
364 };
365 
373 
374 /* User API */
391 uint32_t ztimer_set(ztimer_clock_t *clock, ztimer_t *timer, uint32_t val);
392 
402 unsigned ztimer_is_set(const ztimer_clock_t *clock, const ztimer_t *timer);
403 
421 bool ztimer_remove(ztimer_clock_t *clock, ztimer_t *timer);
422 
438 void ztimer_set_msg(ztimer_clock_t *clock, ztimer_t *timer, uint32_t offset,
439  msg_t *msg, kernel_pid_t target_pid);
440 
459  uint32_t timeout);
460 
461 /* created with dist/tools/define2u16.py */
462 #define MSG_ZTIMER 0xc83e
473 
485 {
486 #if MODULE_ZTIMER_NOW64
487  if (1) {
488 #elif MODULE_ZTIMER_EXTEND
489  if (clock->max_value < UINT32_MAX) {
490 #else
491  if (0) {
492 #endif
493  return _ztimer_now_extend(clock);
494  }
495  else {
496  return clock->ops->now(clock);
497  }
498 }
499 
518 void ztimer_periodic_wakeup(ztimer_clock_t *clock, uint32_t *last_wakeup,
519  uint32_t period);
520 
527 void ztimer_sleep(ztimer_clock_t *clock, uint32_t duration);
528 
537 static inline void ztimer_spin(ztimer_clock_t *clock, uint32_t duration)
538 {
539  uint32_t end = ztimer_now(clock) + duration;
540 
541  /* Rely on integer overflow. `end - now` will be smaller than `duration`,
542  * counting down, until it underflows to UINT32_MAX. Loop ends then. */
543  while ((end - ztimer_now(clock)) <= duration) {}
544 }
545 
557 void ztimer_set_wakeup(ztimer_clock_t *clock, ztimer_t *timer, uint32_t offset,
558  kernel_pid_t pid);
559 
571  uint32_t timeout);
572 
584  uint32_t timeout);
585 
597  uint32_t timeout);
598 
602 void ztimer_init(void);
603 
604 #if defined(MODULE_ZTIMER_EXTEND) || defined(DOXYGEN)
615 static inline void ztimer_init_extend(ztimer_clock_t *clock)
616 {
617  if (clock->max_value < UINT32_MAX) {
618  clock->ops->set(clock, clock->max_value >> 1);
619  }
620 }
621 #endif /* MODULE_ZTIMER_EXTEND */
622 
623 /* default ztimer virtual devices */
627 extern ztimer_clock_t *const ZTIMER_USEC;
628 
632 extern ztimer_clock_t *const ZTIMER_MSEC;
633 
637 extern ztimer_clock_t *const ZTIMER_SEC;
638 
653 extern ztimer_clock_t *const ZTIMER_USEC_BASE;
654 
672 extern ztimer_clock_t *const ZTIMER_MSEC_BASE;
673 
674 #ifdef __cplusplus
675 }
676 #endif
677 
678 #endif /* ZTIMER_H */
int16_t kernel_pid_t
Unique process identifier.
Definition: sched.h:134
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.
ztimer_clock_t *const ZTIMER_SEC
Default ztimer second clock.
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:537
uint32_t ztimer_now_t
type for ztimer_now() result
Definition: ztimer.h:302
static ztimer_now_t ztimer_now(ztimer_clock_t *clock)
Get the current time from a clock.
Definition: ztimer.h:484
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:615
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
ztimer_clock_t *const ZTIMER_USEC_BASE
Base ztimer for the microsecond clock (ZTIMER_USEC)
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.
Mutex for thread synchronization.
Recursive Mutex for thread synchronization.
Scheduler API definition.
Describes a message object which can be sent between threads.
Definition: msg.h:185
Mutex structure.
Definition: mutex.h:123
Mutex structure.
Definition: rmutex.h:43
Minimum information for each timer.
Definition: ztimer.h:294
uint32_t offset
offset from last timer in list
Definition: ztimer.h:296
ztimer_base_t * next
next timer in list
Definition: ztimer.h:295
ztimer device structure
Definition: ztimer.h:348
uint16_t adjust_sleep
will be subtracted on every sleep(), in addition to adjust_set
Definition: ztimer.h:353
uint32_t lower_last
timer value at last now() call
Definition: ztimer.h:358
uint32_t max_value
maximum relative timer value
Definition: ztimer.h:357
ztimer_now_t checkpoint
cumulated time at last now() call
Definition: ztimer.h:359
ztimer_base_t * last
last timer in queue, for _is_set()
Definition: ztimer.h:351
ztimer_base_t list
list of active timers
Definition: ztimer.h:349
uint16_t adjust_set
will be subtracted on every set()
Definition: ztimer.h:352
const ztimer_ops_t * ops
pointer to methods structure
Definition: ztimer.h:350
uint8_t block_pm_mode
min.
Definition: ztimer.h:362
ztimer backend method structure
Definition: ztimer.h:324
uint32_t(* now)(ztimer_clock_t *clock)
Get the current count of the timer.
Definition: ztimer.h:336
void(* set)(ztimer_clock_t *clock, uint32_t val)
Set a new timer target.
Definition: ztimer.h:330
ztimer structure
Definition: ztimer.h:311
void * arg
timer callback argument
Definition: ztimer.h:314
ztimer_base_t base
clock list entry
Definition: ztimer.h:312