v2.0.0
time.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#ifndef _PICO_TIME_H
8#define _PICO_TIME_H
9
10#include "pico.h"
11#include "hardware/timer.h"
12
13#ifdef __cplusplus
14extern "C" {
15#endif
16
32// PICO_CONFIG: PARAM_ASSERTIONS_ENABLED_PICO_TIME, Enable/disable assertions in the pico_time module, type=bool, default=0, group=pico_time
33#ifndef PARAM_ASSERTIONS_ENABLED_PICO_TIME
34#ifdef PARAM_ASSERTIONS_ENABLED_PICO_TIME // backwards compatibility with SDK < 2.0.0
35#define PARAM_ASSERTIONS_ENABLED_PICO_TIME PARAM_ASSERTIONS_ENABLED_TIME
36#else
37#define PARAM_ASSERTIONS_ENABLED_PICO_TIME 0
38#endif
39#endif
40
41// PICO_CONFIG: PICO_TIME_SLEEP_OVERHEAD_ADJUST_US, How many microseconds to wake up early (and then busy_wait) to account for timer overhead when sleeping in low power mode, type=int, default=6, group=pico_time
42#ifndef PICO_TIME_SLEEP_OVERHEAD_ADJUST_US
43#define PICO_TIME_SLEEP_OVERHEAD_ADJUST_US 6
44#endif
45
66 static inline absolute_time_t get_absolute_time(void) {
67 absolute_time_t t;
68 update_us_since_boot(&t, time_us_64());
69 return t;
70}
71
72static inline uint32_t us_to_ms(uint64_t us) {
73 if (us >> 32u) {
74 return (uint32_t)(us / 1000u);
75 } else {
76 return ((uint32_t)us) / 1000u;
77 }
78}
79
87 static inline uint32_t to_ms_since_boot(absolute_time_t t) {
88 uint64_t us = to_us_since_boot(t);
89 return us_to_ms(us);
90}
91
99 static inline absolute_time_t delayed_by_us(const absolute_time_t t, uint64_t us) {
100 absolute_time_t t2;
101 uint64_t base = to_us_since_boot(t);
102 uint64_t delayed = base + us;
103 if ((int64_t)delayed < 0) {
104 // absolute_time_t (to allow for signed time deltas) is never greater than INT64_MAX which == at_the_end_of_time
105 delayed = INT64_MAX;
106 }
107 update_us_since_boot(&t2, delayed);
108 return t2;
109}
110
118 static inline absolute_time_t delayed_by_ms(const absolute_time_t t, uint32_t ms) {
119 absolute_time_t t2;
120 uint64_t base = to_us_since_boot(t);
121 uint64_t delayed = base + ms * 1000ull;
122 if ((int64_t)delayed < 0) {
123 // absolute_time_t (to allow for signed time deltas) is never greater than INT64_MAX which == at_the_end_of_time
124 delayed = INT64_MAX;
125 }
126 update_us_since_boot(&t2, delayed);
127 return t2;
128}
129
136 static inline absolute_time_t make_timeout_time_us(uint64_t us) {
137 return delayed_by_us(get_absolute_time(), us);
138}
139
146 static inline absolute_time_t make_timeout_time_ms(uint32_t ms) {
147 return delayed_by_ms(get_absolute_time(), ms);
148}
149
161 static inline int64_t absolute_time_diff_us(absolute_time_t from, absolute_time_t to) {
162 return (int64_t)(to_us_since_boot(to) - to_us_since_boot(from));
163}
164
172 static inline absolute_time_t absolute_time_min(absolute_time_t a, absolute_time_t b) {
173 return to_us_since_boot(a) < to_us_since_boot(b) ? a : b;
174}
175
181extern const absolute_time_t at_the_end_of_time;
182
189 static inline bool is_at_the_end_of_time(absolute_time_t t) {
190 return to_us_since_boot(t) == to_us_since_boot(at_the_end_of_time);
191}
192
196extern const absolute_time_t nil_time;
197
204 static inline bool is_nil_time(absolute_time_t t) {
205 return !to_us_since_boot(t);
206}
207
237void sleep_until(absolute_time_t target);
238
247void sleep_us(uint64_t us);
248
256void sleep_ms(uint32_t ms);
257
291bool best_effort_wfe_or_timeout(absolute_time_t timeout_timestamp);
292
311// PICO_CONFIG: PICO_TIME_DEFAULT_ALARM_POOL_DISABLED, Disable the default alarm pool, type=bool, default=0, advanced=true, group=pico_time
312#ifndef PICO_TIME_DEFAULT_ALARM_POOL_DISABLED
325#define PICO_TIME_DEFAULT_ALARM_POOL_DISABLED 0
326#endif
327
328// PICO_CONFIG: PICO_TIME_DEFAULT_ALARM_POOL_HARDWARE_ALARM_NUM, Select which HW alarm is used for the default alarm pool, min=0, max=3, default=3, advanced=true, group=pico_time
329#ifndef PICO_TIME_DEFAULT_ALARM_POOL_HARDWARE_ALARM_NUM
335#define PICO_TIME_DEFAULT_ALARM_POOL_HARDWARE_ALARM_NUM 3
336#endif
337
338// PICO_CONFIG: PICO_TIME_DEFAULT_ALARM_POOL_MAX_TIMERS, Selects the maximum number of concurrent timers in the default alarm pool, min=0, max=255, default=16, advanced=true, group=pico_time
339#ifndef PICO_TIME_DEFAULT_ALARM_POOL_MAX_TIMERS
348#define PICO_TIME_DEFAULT_ALARM_POOL_MAX_TIMERS 16
349#endif
350
365 typedef int32_t alarm_id_t; // note this is signed because we use <0 as a meaningful error value
366
376 typedef int64_t (*alarm_callback_t)(alarm_id_t id, void *user_data);
377
378typedef struct alarm_pool alarm_pool_t;
379typedef void alarm_pool_timer_t;
380
385void alarm_pool_init_default(void);
386void runtime_init_default_alarm_pool(void);
387
388#if !PICO_TIME_DEFAULT_ALARM_POOL_DISABLED
396 alarm_pool_t *alarm_pool_get_default(void);
397#endif
398
399 alarm_pool_t *alarm_pool_create_on_timer(alarm_pool_timer_t *timer, uint timer_alarm_num, uint max_timers);
400
401alarm_pool_timer_t *alarm_pool_timer_for_timer_num(uint timer_num);
402
403alarm_pool_timer_t *alarm_pool_get_default_timer(void);
404
423 static inline alarm_pool_t *alarm_pool_create(uint timer_alarm_num, uint max_timers) {
424 return alarm_pool_create_on_timer(alarm_pool_get_default_timer(), timer_alarm_num, max_timers);
425}
426
427 alarm_pool_t *alarm_pool_create_on_timer_with_unused_hardware_alarm(alarm_pool_timer_t *timer, uint max_timers);
428
446 static inline alarm_pool_t *alarm_pool_create_with_unused_hardware_alarm(uint max_timers) {
447 return alarm_pool_create_on_timer_with_unused_hardware_alarm(alarm_pool_get_default_timer(), max_timers);
448}
449
456uint alarm_pool_timer_alarm_num(alarm_pool_t *pool);
457// backwards compatibility
458static inline uint alarm_pool_hardware_alarm_num(alarm_pool_t *pool) {
459 return alarm_pool_timer_alarm_num(pool);
460}
467uint alarm_pool_core_num(alarm_pool_t *pool);
468
474void alarm_pool_destroy(alarm_pool_t *pool);
475
497 alarm_id_t alarm_pool_add_alarm_at(alarm_pool_t *pool, absolute_time_t time, alarm_callback_t callback, void *user_data, bool fire_if_past);
498
516 alarm_id_t alarm_pool_add_alarm_at_force_in_context(alarm_pool_t *pool, absolute_time_t time, alarm_callback_t callback,
517 void *user_data);
539 static inline alarm_id_t alarm_pool_add_alarm_in_us(alarm_pool_t *pool, uint64_t us, alarm_callback_t callback, void *user_data, bool fire_if_past) {
540 return alarm_pool_add_alarm_at(pool, delayed_by_us(get_absolute_time(), us), callback, user_data, fire_if_past);
541}
542
564 static inline alarm_id_t alarm_pool_add_alarm_in_ms(alarm_pool_t *pool, uint32_t ms, alarm_callback_t callback, void *user_data, bool fire_if_past) {
565 return alarm_pool_add_alarm_at(pool, delayed_by_ms(get_absolute_time(), ms), callback, user_data, fire_if_past);
566}
567
578int64_t alarm_pool_remaining_alarm_time_us(alarm_pool_t *pool, alarm_id_t alarm_id);
579
590int32_t alarm_pool_remaining_alarm_time_ms(alarm_pool_t *pool, alarm_id_t alarm_id);
591
600bool alarm_pool_cancel_alarm(alarm_pool_t *pool, alarm_id_t alarm_id);
601
602#if !PICO_TIME_DEFAULT_ALARM_POOL_DISABLED
623 static inline alarm_id_t add_alarm_at(absolute_time_t time, alarm_callback_t callback, void *user_data, bool fire_if_past) {
624 return alarm_pool_add_alarm_at(alarm_pool_get_default(), time, callback, user_data, fire_if_past);
625}
626
647 static inline alarm_id_t add_alarm_in_us(uint64_t us, alarm_callback_t callback, void *user_data, bool fire_if_past) {
648 return alarm_pool_add_alarm_in_us(alarm_pool_get_default(), us, callback, user_data, fire_if_past);
649}
650
671 static inline alarm_id_t add_alarm_in_ms(uint32_t ms, alarm_callback_t callback, void *user_data, bool fire_if_past) {
672 return alarm_pool_add_alarm_in_ms(alarm_pool_get_default(), ms, callback, user_data, fire_if_past);
673}
681 static inline bool cancel_alarm(alarm_id_t alarm_id) {
682 return alarm_pool_cancel_alarm(alarm_pool_get_default(), alarm_id);
683}
684
695int64_t remaining_alarm_time_us(alarm_id_t alarm_id);
696
706int32_t remaining_alarm_time_ms(alarm_id_t alarm_id);
707
708#endif
709
720typedef struct repeating_timer repeating_timer_t;
721
728 typedef bool (*repeating_timer_callback_t)(repeating_timer_t *rt);
729
735 struct repeating_timer {
736 int64_t delay_us;
737 alarm_pool_t *pool;
738 alarm_id_t alarm_id;
739 repeating_timer_callback_t callback;
740 void *user_data;
741};
742
761bool alarm_pool_add_repeating_timer_us(alarm_pool_t *pool, int64_t delay_us, repeating_timer_callback_t callback, void *user_data, repeating_timer_t *out);
762
781 static inline bool alarm_pool_add_repeating_timer_ms(alarm_pool_t *pool, int32_t delay_ms, repeating_timer_callback_t callback, void *user_data, repeating_timer_t *out) {
782 return alarm_pool_add_repeating_timer_us(pool, delay_ms * (int64_t)1000, callback, user_data, out);
783}
784
785#if !PICO_TIME_DEFAULT_ALARM_POOL_DISABLED
803 static inline bool add_repeating_timer_us(int64_t delay_us, repeating_timer_callback_t callback, void *user_data, repeating_timer_t *out) {
804 return alarm_pool_add_repeating_timer_us(alarm_pool_get_default(), delay_us, callback, user_data, out);
805}
806
824 static inline bool add_repeating_timer_ms(int32_t delay_ms, repeating_timer_callback_t callback, void *user_data, repeating_timer_t *out) {
825 return alarm_pool_add_repeating_timer_us(alarm_pool_get_default(), delay_ms * (int64_t)1000, callback, user_data, out);
826}
827#endif
828
836bool cancel_repeating_timer(repeating_timer_t *timer);
837
838#ifdef __cplusplus
839}
840#endif
841
842#endif
alarm_pool_cancel_alarm
bool alarm_pool_cancel_alarm(alarm_pool_t *pool, alarm_id_t alarm_id)
Cancel an alarm.
Definition: time.c:346
alarm_pool_add_alarm_in_us
static alarm_id_t alarm_pool_add_alarm_in_us(alarm_pool_t *pool, uint64_t us, alarm_callback_t callback, void *user_data, bool fire_if_past)
Add an alarm callback to be called after a delay specified in microseconds.
Definition: time.h:539
alarm_pool_create
static alarm_pool_t * alarm_pool_create(uint timer_alarm_num, uint max_timers)
Create an alarm pool.
Definition: time.h:423
alarm_pool_remaining_alarm_time_us
int64_t alarm_pool_remaining_alarm_time_us(alarm_pool_t *pool, alarm_id_t alarm_id)
Return the time remaining before the next trigger of an alarm.
Definition: time.c:498
alarm_pool_remaining_alarm_time_ms
int32_t alarm_pool_remaining_alarm_time_ms(alarm_pool_t *pool, alarm_id_t alarm_id)
Return the time remaining before the next trigger of an alarm.
Definition: time.c:526
alarm_pool_core_num
uint alarm_pool_core_num(alarm_pool_t *pool)
Return the core number the alarm pool was initialized on (and hence callbacks are called on)
Definition: time.c:372
alarm_pool_get_default
alarm_pool_t * alarm_pool_get_default(void)
The default alarm pool used when alarms are added without specifying an alarm pool,...
Definition: time.c:100
remaining_alarm_time_us
int64_t remaining_alarm_time_us(alarm_id_t alarm_id)
Return the time remaining before the next trigger of an alarm.
Definition: time.c:533
remaining_alarm_time_ms
int32_t remaining_alarm_time_ms(alarm_id_t alarm_id)
Return the time remaining before the next trigger of an alarm.
Definition: time.c:537
add_alarm_in_us
static alarm_id_t add_alarm_in_us(uint64_t us, alarm_callback_t callback, void *user_data, bool fire_if_past)
Add an alarm callback to be called after a delay specified in microseconds.
Definition: time.h:647
alarm_pool_add_alarm_in_ms
static alarm_id_t alarm_pool_add_alarm_in_ms(alarm_pool_t *pool, uint32_t ms, alarm_callback_t callback, void *user_data, bool fire_if_past)
Add an alarm callback to be called after a delay specified in milliseconds.
Definition: time.h:564
alarm_pool_create_with_unused_hardware_alarm
static alarm_pool_t * alarm_pool_create_with_unused_hardware_alarm(uint max_timers)
Create an alarm pool, claiming an used timer_alarm to back it.
Definition: time.h:446
alarm_pool_add_alarm_at_force_in_context
alarm_id_t alarm_pool_add_alarm_at_force_in_context(alarm_pool_t *pool, absolute_time_t time, alarm_callback_t callback, void *user_data)
Add an alarm callback to be called at or after a specific time.
Definition: time.c:313
add_alarm_in_ms
static alarm_id_t add_alarm_in_ms(uint32_t ms, alarm_callback_t callback, void *user_data, bool fire_if_past)
Add an alarm callback to be called after a delay specified in milliseconds.
Definition: time.h:671
alarm_id_t
int32_t alarm_id_t
The identifier for an alarm.
Definition: time.h:365
alarm_pool_init_default
void alarm_pool_init_default(void)
Create the default alarm pool (if not already created or disabled)
Definition: time.c:95
alarm_pool_add_alarm_at
alarm_id_t alarm_pool_add_alarm_at(alarm_pool_t *pool, absolute_time_t time, alarm_callback_t callback, void *user_data, bool fire_if_past)
Add an alarm callback to be called at a specific time.
Definition: time.c:304
alarm_callback_t
int64_t(* alarm_callback_t)(alarm_id_t id, void *user_data)
User alarm callback.
Definition: time.h:376
alarm_pool_destroy
void alarm_pool_destroy(alarm_pool_t *pool)
Destroy the alarm pool, cancelling all alarms and freeing up the underlying timer_alarm.
Definition: time.c:290
add_alarm_at
static alarm_id_t add_alarm_at(absolute_time_t time, alarm_callback_t callback, void *user_data, bool fire_if_past)
Add an alarm callback to be called at a specific time.
Definition: time.h:623
cancel_alarm
static bool cancel_alarm(alarm_id_t alarm_id)
Cancel an alarm from the default alarm pool.
Definition: time.h:681
alarm_pool_timer_alarm_num
uint alarm_pool_timer_alarm_num(alarm_pool_t *pool)
Return the timer alarm used by an alarm pool.
Definition: time.c:368
time_us_64
uint64_t time_us_64(void)
Return the current 64 bit timestamp value in microseconds for the default timer instance.
Definition: timer.c:125
add_repeating_timer_ms
static bool add_repeating_timer_ms(int32_t delay_ms, repeating_timer_callback_t callback, void *user_data, repeating_timer_t *out)
Add a repeating timer that is called repeatedly at the specified interval in milliseconds.
Definition: time.h:824
repeating_timer_callback_t
bool(* repeating_timer_callback_t)(repeating_timer_t *rt)
Callback for a repeating timer.
Definition: time.h:728
alarm_pool_add_repeating_timer_us
bool alarm_pool_add_repeating_timer_us(alarm_pool_t *pool, int64_t delay_us, repeating_timer_callback_t callback, void *user_data, repeating_timer_t *out)
Add a repeating timer that is called repeatedly at the specified interval in microseconds.
Definition: time.c:470
add_repeating_timer_us
static bool add_repeating_timer_us(int64_t delay_us, repeating_timer_callback_t callback, void *user_data, repeating_timer_t *out)
Add a repeating timer that is called repeatedly at the specified interval in microseconds.
Definition: time.h:803
cancel_repeating_timer
bool cancel_repeating_timer(repeating_timer_t *timer)
Cancel a repeating timer.
Definition: time.c:481
alarm_pool_add_repeating_timer_ms
static bool alarm_pool_add_repeating_timer_ms(alarm_pool_t *pool, int32_t delay_ms, repeating_timer_callback_t callback, void *user_data, repeating_timer_t *out)
Add a repeating timer that is called repeatedly at the specified interval in milliseconds.
Definition: time.h:781
sleep_until
void sleep_until(absolute_time_t target)
Wait until after the given timestamp to return.
Definition: time.c:384
sleep_ms
void sleep_ms(uint32_t ms)
Wait for the given number of milliseconds before returning.
Definition: time.c:431
best_effort_wfe_or_timeout
bool best_effort_wfe_or_timeout(absolute_time_t timeout_timestamp)
Helper method for blocking on a timeout.
Definition: time.c:435
sleep_us
void sleep_us(uint64_t us)
Wait for the given number of microseconds before returning.
Definition: time.c:414
is_nil_time
static bool is_nil_time(absolute_time_t t)
Determine if the given timestamp is nil.
Definition: time.h:204
to_us_since_boot
static uint64_t to_us_since_boot(absolute_time_t t)
convert an absolute_time_t into a number of microseconds since boot.
Definition: types.h:52
absolute_time_diff_us
static int64_t absolute_time_diff_us(absolute_time_t from, absolute_time_t to)
Return the difference in microseconds between two timestamps.
Definition: time.h:161
is_at_the_end_of_time
static bool is_at_the_end_of_time(absolute_time_t t)
Determine if the given timestamp is "at_the_end_of_time".
Definition: time.h:189
absolute_time_min
static absolute_time_t absolute_time_min(absolute_time_t a, absolute_time_t b)
Return the earlier of two timestamps.
Definition: time.h:172
get_absolute_time
static absolute_time_t get_absolute_time(void)
Return a representation of the current time.
Definition: time.h:66
make_timeout_time_us
static absolute_time_t make_timeout_time_us(uint64_t us)
Convenience method to get the timestamp a number of microseconds from the current time.
Definition: time.h:136
delayed_by_us
static absolute_time_t delayed_by_us(const absolute_time_t t, uint64_t us)
Return a timestamp value obtained by adding a number of microseconds to another timestamp.
Definition: time.h:99
delayed_by_ms
static absolute_time_t delayed_by_ms(const absolute_time_t t, uint32_t ms)
Return a timestamp value obtained by adding a number of milliseconds to another timestamp.
Definition: time.h:118
absolute_time_t
uint64_t absolute_time_t
An opaque 64 bit timestamp in microseconds.
Definition: types.h:43
nil_time
const absolute_time_t nil_time
The timestamp representing a null timestamp.
make_timeout_time_ms
static absolute_time_t make_timeout_time_ms(uint32_t ms)
Convenience method to get the timestamp a number of milliseconds from the current time.
Definition: time.h:146
to_ms_since_boot
static uint32_t to_ms_since_boot(absolute_time_t t)
Convert a timestamp into a number of milliseconds since boot.
Definition: time.h:87
at_the_end_of_time
const absolute_time_t at_the_end_of_time
The timestamp representing the end of time; this is actually not the maximum possible timestamp,...
update_us_since_boot
static void update_us_since_boot(absolute_time_t *t, uint64_t us_since_boot)
update an absolute_time_t value to represent a given number of microseconds since boot
Definition: types.h:67
pico.h
timer.h
alarm_pool
Definition: time.c:28
repeating_timer
Information about a repeating timer.
Definition: time.h:735