Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sys/ztimer/xtimer_compat: provide more fallback options #20494

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
191 changes: 165 additions & 26 deletions sys/include/ztimer/xtimer_compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
/* make sure to overwrite potentially conflicting XTIMER_WIDTH definition from
* board.h by eagerly including it */
#include "board.h"
#include "busy_wait.h"
#include "timex.h"
#ifdef MODULE_CORE_MSG
#include "msg.h"
Expand Down Expand Up @@ -64,10 +65,27 @@
#define XTIMER_BACKOFF 1
#endif

/**
* @brief Generate a link-time failure if a function is used that can not be
* implemented with the selected backends.
*/
#define _XTIMER_BACKEND_NOT_IMPLEMENTED extern void xtimer_function_called_but_no_backend_available(void); \

Check warning on line 72 in sys/include/ztimer/xtimer_compat.h

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters
xtimer_function_called_but_no_backend_available()

typedef ztimer_t xtimer_t;
typedef uint32_t xtimer_ticks32_t;

Check warning on line 76 in sys/include/ztimer/xtimer_compat.h

View workflow job for this annotation

GitHub Actions / static-tests

Uncrustify proposes the following patch: --- a/sys/include/ztimer/xtimer_compat.h +++ b/sys/include/ztimer/xtimer_compat.h @@ -69,8 +69,9 @@ extern "C" { * @brief Generate a link-time failure if a function is used that can not be * implemented with the selected backends. */ -#define _XTIMER_BACKEND_NOT_IMPLEMENTED extern void xtimer_function_called_but_no_backend_available(void); \ - xtimer_function_called_but_no_backend_available() +#define _XTIMER_BACKEND_NOT_IMPLEMENTED extern void xtimer_function_called_but_no_backend_available( \ + void); \ + xtimer_function_called_but_no_backend_available() typedef ztimer_t xtimer_t; typedef uint32_t xtimer_ticks32_t;
typedef uint64_t xtimer_ticks64_t;

static inline uint32_t _div_round_up(uint32_t a, uint32_t b)
{
return (a + b - 1) / b;
}

static inline uint32_t _div_round_up64(uint64_t a, uint32_t b)
{
return (a + b - 1) / b;
}

static inline void xtimer_init(void)
{
ztimer_init();
Expand All @@ -88,6 +106,11 @@
return ticks;
}

static inline uint32_t xtimer_msec_from_ticks(xtimer_ticks32_t ticks)
{
return ticks * US_PER_MS;
}

static inline uint64_t xtimer_usec_from_ticks64(xtimer_ticks64_t ticks)
{
return ticks;
Expand All @@ -105,12 +128,28 @@

static inline xtimer_ticks32_t xtimer_now(void)
{
return ztimer_now(ZTIMER_USEC);
if (IS_USED(MODULE_ZTIMER_USEC)) {
return ztimer_now(ZTIMER_USEC);
}
else if (IS_USED(MODULE_ZTIMER_MSEC)) {
return ztimer_now(ZTIMER_MSEC) * US_PER_MS;
}
else {
return 0;
benpicco marked this conversation as resolved.
Show resolved Hide resolved
}
}

static inline uint32_t xtimer_now_usec(void)
{
return ztimer_now(ZTIMER_USEC);
if (IS_USED(MODULE_ZTIMER_USEC)) {
return ztimer_now(ZTIMER_USEC);
}
else if (IS_USED(MODULE_ZTIMER_MSEC)) {
return ztimer_now(ZTIMER_MSEC) * US_PER_MS;
}
else {
return 0;
}
}

static inline void _ztimer_sleep_scale(ztimer_clock_t *clock, uint32_t time,
Expand All @@ -129,7 +168,7 @@
static inline void xtimer_sleep(uint32_t seconds)
{
/* TODO: use ZTIMER_SEC */
if (IS_ACTIVE(MODULE_ZTIMER_MSEC)) {
if (IS_USED(MODULE_ZTIMER_MSEC)) {
_ztimer_sleep_scale(ZTIMER_MSEC, seconds, MS_PER_SEC);
}
else {
Expand All @@ -139,22 +178,33 @@

static inline void xtimer_msleep(uint32_t milliseconds)
{
if (IS_ACTIVE(MODULE_ZTIMER_MSEC)) {
if (IS_USED(MODULE_ZTIMER_MSEC)) {
ztimer_sleep(ZTIMER_MSEC, milliseconds);
}
else {
else if (IS_USED(MODULE_ZTIMER_USEC)) {
_ztimer_sleep_scale(ZTIMER_USEC, milliseconds, US_PER_MS);
}
else {
busy_wait_us(US_PER_MS * milliseconds);
}
}

static inline void xtimer_usleep(uint32_t microseconds)
{
ztimer_sleep(ZTIMER_USEC, microseconds);
if (IS_USED(MODULE_ZTIMER_USEC)) {
ztimer_sleep(ZTIMER_USEC, microseconds);
}
else if (IS_USED(MODULE_ZTIMER_MSEC)) {
ztimer_sleep(ZTIMER_MSEC, _div_round_up(microseconds, US_PER_MS));
}
else {
busy_wait_us(microseconds);
}
}

static inline void xtimer_nanosleep(uint32_t nanoseconds)
{
ztimer_sleep(ZTIMER_USEC, nanoseconds / NS_PER_US);
xtimer_usleep(nanoseconds / NS_PER_US);
}

static inline void xtimer_tsleep32(xtimer_ticks32_t ticks)
Expand All @@ -176,60 +226,141 @@

static inline void xtimer_set(xtimer_t *timer, uint32_t offset)
{
ztimer_set(ZTIMER_USEC, timer, offset);
if (IS_USED(MODULE_ZTIMER_USEC)) {
ztimer_set(ZTIMER_USEC, timer, offset);
}
else if (IS_USED(MODULE_ZTIMER_MSEC)) {
ztimer_set(ZTIMER_MSEC, timer, _div_round_up(offset, US_PER_MS));
}
else {
_XTIMER_BACKEND_NOT_IMPLEMENTED;
}
}

static inline void xtimer_remove(xtimer_t *timer)
{
ztimer_remove(ZTIMER_USEC, timer);
if (IS_USED(MODULE_ZTIMER_USEC)) {
ztimer_remove(ZTIMER_USEC, timer);
}
else if (IS_USED(MODULE_ZTIMER_MSEC)) {
ztimer_remove(ZTIMER_MSEC, timer);
}
else {
_XTIMER_BACKEND_NOT_IMPLEMENTED;
}
}

static inline void xtimer_set_msg(xtimer_t *timer, uint32_t offset, msg_t *msg,
kernel_pid_t target_pid)
{
ztimer_set_msg(ZTIMER_USEC, timer, offset, msg, target_pid);
if (IS_USED(MODULE_ZTIMER_USEC)) {
ztimer_set_msg(ZTIMER_USEC, timer, offset, msg, target_pid);
}
else if (IS_USED(MODULE_ZTIMER_MSEC)) {
ztimer_set_msg(ZTIMER_MSEC, timer, _div_round_up(offset, US_PER_MS),
msg, target_pid);
}
else {
_XTIMER_BACKEND_NOT_IMPLEMENTED;
}
}

static inline void xtimer_periodic_wakeup(xtimer_ticks32_t *last_wakeup,
uint32_t period)
{
ztimer_periodic_wakeup(ZTIMER_USEC, last_wakeup, period);
if (IS_USED(MODULE_ZTIMER_USEC)) {
ztimer_periodic_wakeup(ZTIMER_USEC, last_wakeup, period);
}
else if (IS_USED(MODULE_ZTIMER_MSEC)) {
ztimer_periodic_wakeup(ZTIMER_MSEC, last_wakeup, _div_round_up(period, US_PER_MS));
}
else {
_XTIMER_BACKEND_NOT_IMPLEMENTED;
}
}

static inline int xtimer_msg_receive_timeout(msg_t *msg, uint32_t timeout)
{
return ztimer_msg_receive_timeout(ZTIMER_USEC, msg, timeout);
if (IS_USED(MODULE_ZTIMER_USEC)) {
return ztimer_msg_receive_timeout(ZTIMER_USEC, msg, timeout);
}
else if (IS_USED(MODULE_ZTIMER_MSEC)) {
return ztimer_msg_receive_timeout(ZTIMER_MSEC, msg, _div_round_up(timeout, US_PER_MS));
}
else {
_XTIMER_BACKEND_NOT_IMPLEMENTED;
}
}

static inline void xtimer_set_wakeup(xtimer_t *timer, uint32_t offset,
kernel_pid_t pid)
{
ztimer_set_wakeup(ZTIMER_USEC, timer, offset, pid);
if (IS_USED(MODULE_ZTIMER_USEC)) {
ztimer_set_wakeup(ZTIMER_USEC, timer, offset, pid);
}
else if (IS_USED(MODULE_ZTIMER_MSEC)) {
ztimer_set_wakeup(ZTIMER_MSEC, timer, _div_round_up(offset, US_PER_MS), pid);
}
else {
_XTIMER_BACKEND_NOT_IMPLEMENTED;
}
}

static inline int xtimer_mutex_lock_timeout(mutex_t *mutex, uint64_t us)
{
assert(us <= UINT32_MAX);
if (ztimer_mutex_lock_timeout(ZTIMER_USEC, mutex, (uint32_t)us)) {
/* Impedance matching required: Convert -ECANCELED error code to -1: */
return -1;
int res;

if (IS_USED(MODULE_ZTIMER_USEC)) {
assert(us <= UINT32_MAX);
res = ztimer_mutex_lock_timeout(ZTIMER_USEC, mutex, (uint32_t)us);
}
return 0;
else if (IS_USED(MODULE_ZTIMER_USEC)) {
us = _div_round_up64(us, US_PER_MS);
assert(us <= UINT32_MAX);
res = ztimer_mutex_lock_timeout(ZTIMER_SEC, mutex, (uint32_t)us);
}
else {
_XTIMER_BACKEND_NOT_IMPLEMENTED;
res = -1;
}

/* Impedance matching required: Convert -ECANCELED error code to -1: */
return res ? -1 : 0;
}

static inline int xtimer_rmutex_lock_timeout(rmutex_t *rmutex, uint64_t us)
static inline int xtimer_rmutex_lock_timeout(rmutex_t *mutex, uint64_t us)
{
assert(us <= UINT32_MAX);
if (ztimer_rmutex_lock_timeout(ZTIMER_USEC, rmutex, us)) {
/* Impedance matching required: Convert -ECANCELED error code to -1: */
return -1;
int res;

if (IS_USED(MODULE_ZTIMER_USEC)) {
assert(us <= UINT32_MAX);
res = ztimer_rmutex_lock_timeout(ZTIMER_USEC, mutex, (uint32_t)us);
}
return 0;
else if (IS_USED(MODULE_ZTIMER_USEC)) {
us = _div_round_up64(us, US_PER_MS);
assert(us <= UINT32_MAX);
res = ztimer_rmutex_lock_timeout(ZTIMER_SEC, mutex, (uint32_t)us);
}
else {
_XTIMER_BACKEND_NOT_IMPLEMENTED;
res = -1;
}

/* Impedance matching required: Convert -ECANCELED error code to -1: */
return res ? -1 : 0;
}

static inline void xtimer_set_timeout_flag(xtimer_t *t, uint32_t timeout)
{
ztimer_set_timeout_flag(ZTIMER_USEC, t, timeout);
if (IS_USED(MODULE_ZTIMER_USEC)) {
ztimer_set_timeout_flag(ZTIMER_USEC, t, timeout);
}
else if (IS_USED(MODULE_ZTIMER_USEC)) {
ztimer_set_timeout_flag(ZTIMER_USEC, t, _div_round_up(timeout, US_PER_MS));
}
else {
_XTIMER_BACKEND_NOT_IMPLEMENTED;
}
}

static inline void xtimer_set_timeout_flag64(xtimer_t *t, uint64_t timeout)
Expand All @@ -240,7 +371,15 @@

static inline void xtimer_spin(xtimer_ticks32_t ticks)
{
ztimer_spin(ZTIMER_USEC, xtimer_usec_from_ticks(ticks));
if (IS_USED(MODULE_ZTIMER_USEC)) {
ztimer_spin(ZTIMER_USEC, xtimer_usec_from_ticks(ticks));
}
else if (IS_USED(MODULE_ZTIMER_MSEC)) {
ztimer_spin(ZTIMER_MSEC, xtimer_msec_from_ticks(ticks));
}
else {
busy_wait_us(xtimer_usec_from_ticks(ticks));
}
}

static inline xtimer_ticks32_t xtimer_diff(xtimer_ticks32_t a,
Expand Down
4 changes: 4 additions & 0 deletions sys/ztimer/Makefile.include
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
# ztimer's compatibility wrapper
ifneq (,$(filter ztimer_xtimer_compat,$(USEMODULE)))
PSEUDOMODULES += xtimer

ifeq (,$(filter ztimer_usec,$(USEMODULE)))
$(info $(COLOR_YELLOW)WARNING! xtimer compat without ztimer_usec may be inaccurate$(COLOR_RESET))
endif
endif

MODULES_ZTIMER_ON_RTT_CONFLICT = rtt_rtc gnrc_lwmac gnrc_gomach
Expand Down
Loading