From df8086091f20a72d3e1380376684df39ae922d13 Mon Sep 17 00:00:00 2001 From: Kaspar Schleiser Date: Wed, 15 Dec 2021 11:22:11 +0100 Subject: [PATCH] sys/ztimer: add ztimer64_xtimer_compat The ztimer64_xtimer_compat modules implements the whole xtimer api on top of ztimer64_usec --- makefiles/boards/ztimer_only.dep.mk | 2 +- sys/Makefile.dep | 3 +- sys/include/xtimer.h | 7 +- sys/include/ztimer64.h | 1 + sys/include/ztimer64/xtimer_compat.h | 312 +++++++++++++++++++++++++++ sys/xtimer/Kconfig | 3 +- sys/ztimer/Kconfig | 15 +- sys/ztimer/Makefile.dep | 24 ++- 8 files changed, 347 insertions(+), 20 deletions(-) create mode 100644 sys/include/ztimer64/xtimer_compat.h diff --git a/makefiles/boards/ztimer_only.dep.mk b/makefiles/boards/ztimer_only.dep.mk index f82f98231e..f50810a051 100644 --- a/makefiles/boards/ztimer_only.dep.mk +++ b/makefiles/boards/ztimer_only.dep.mk @@ -5,7 +5,7 @@ # ztimer_xtimer_compat is used. ifneq (,$(filter xtimer,$(USEMODULE))) - ifeq (,$(filter ztimer_xtimer_compat,$(USEMODULE))) + ifeq (,$(filter ztimer_xtimer_compat ztimer64_xtimer_compat,$(USEMODULE))) USEMODULE += xtimer_on_ztimer endif endif diff --git a/sys/Makefile.dep b/sys/Makefile.dep index 550846cd86..ff889f8342 100644 --- a/sys/Makefile.dep +++ b/sys/Makefile.dep @@ -798,7 +798,8 @@ ifneq (,$(filter xtimer,$(USEMODULE))) # will use *ztimer_usec as low-level timer* endif else - # ztimer_xtimer_compat is used, all of *xtimer's API will be mapped on ztimer.* + # ztimer_xtimer_compat is used, all of *xtimer's API will be mapped on ztimer + # or ztimer64 * endif endif diff --git a/sys/include/xtimer.h b/sys/include/xtimer.h index 9246614f21..ad4365cb36 100644 --- a/sys/include/xtimer.h +++ b/sys/include/xtimer.h @@ -39,12 +39,13 @@ #include "sched.h" #include "rmutex.h" -#ifdef MODULE_ZTIMER_XTIMER_COMPAT +#if IS_USED(MODULE_ZTIMER64_XTIMER_COMPAT) +#include "ztimer64/xtimer_compat.h" +#elif IS_USED(MODULE_ZTIMER_XTIMER_COMPAT) #include "ztimer/xtimer_compat.h" #else - #include "board.h" -#ifndef MODULE_XTIMER_ON_ZTIMER +#if !IS_USED(MODULE_XTIMER_ON_ZTIMER) #include "periph_conf.h" #endif diff --git a/sys/include/ztimer64.h b/sys/include/ztimer64.h index 80868e9e7c..d7e8f92c85 100644 --- a/sys/include/ztimer64.h +++ b/sys/include/ztimer64.h @@ -66,6 +66,7 @@ #include +#include "irq.h" #include "mutex.h" #include "msg.h" #include "ztimer.h" diff --git a/sys/include/ztimer64/xtimer_compat.h b/sys/include/ztimer64/xtimer_compat.h new file mode 100644 index 0000000000..42ef4f4e75 --- /dev/null +++ b/sys/include/ztimer64/xtimer_compat.h @@ -0,0 +1,312 @@ +/* + * Copyright (C) 2019 Kaspar Schleiser + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup sys_ztimer_util + * @{ + * @file + * @brief ztimer64 xtimer wrapper interface + * + * Please check out xtimer's documentation for usage. + * + * @author Kaspar Schleiser + */ +#ifndef ZTIMER64_XTIMER_COMPAT_H +#define ZTIMER64_XTIMER_COMPAT_H + +#include +#include +#include + +/* make sure to overwrite potentially conflicting XTIMER_WIDTH definition from + * board.h by eagerly including it */ +#include "board.h" +#include "div.h" +#include "timex.h" +#ifdef MODULE_CORE_MSG +#include "msg.h" +#endif /* MODULE_CORE_MSG */ +#include "mutex.h" +#include "sched.h" + +#include "ztimer.h" +#include "ztimer64.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* the xtimer API is documented elsewhere. This is just an (incomplete) wrapper, + * so skip doxygen. + */ +#ifndef DOXYGEN + +/* ztimer clocks with width lower than 32 bit get extended to 32 bit in software + * via ztimer_extend. So no matter what was defined elsewhere, we overwrite it + */ +#ifdef XTIMER_WIDTH +#undef XTIMER_WIDTH +#endif + +#define XTIMER_WIDTH (32) +#define XTIMER_MASK (0) + +/** + * a default XTIMER_BACKOFF value, this is not used by ztimer, but other code + * uses this value to set timers + */ +#ifndef XTIMER_BACKOFF +#define XTIMER_BACKOFF 1 +#endif + +typedef ztimer64_t xtimer_t; +typedef uint32_t xtimer_ticks32_t; +typedef uint64_t xtimer_ticks64_t; +typedef void (*xtimer_callback_t)(void *); + +static inline void xtimer_init(void) +{ + ztimer64_init(); +} + +static inline xtimer_ticks32_t xtimer_ticks(uint32_t ticks) +{ + return ticks; +} + +static inline xtimer_ticks32_t xtimer_now(void) +{ + return ztimer64_now(ZTIMER64_USEC); +} + +static inline uint32_t _xtimer_now(void) +{ + return ztimer64_now(ZTIMER64_USEC); +} + +static inline xtimer_ticks64_t xtimer_now64(void) +{ + return ztimer64_now(ZTIMER64_USEC); +} + +static inline void xtimer_usleep64(uint64_t microseconds) +{ + ztimer64_sleep(ZTIMER64_USEC, microseconds); +} + +static inline uint32_t xtimer_now_usec(void) +{ + return ztimer64_now(ZTIMER64_USEC); +} + +static inline uint64_t xtimer_now_usec64(void) +{ + return ztimer64_now(ZTIMER64_USEC); +} + +static inline void xtimer_sleep(uint32_t seconds) +{ + /* TODO: use ZTIMER64_SEC */ + if (IS_ACTIVE(MODULE_ZTIMER64_MSEC)) { + ztimer64_sleep(ZTIMER64_MSEC, ((uint64_t)seconds) * 1000LLU); + } + else { + ztimer64_sleep(ZTIMER64_USEC, ((uint64_t)seconds) * 1000000LLU); + } +} + +static inline void xtimer_msleep(uint32_t milliseconds) +{ + if (IS_ACTIVE(MODULE_ZTIMER_MSEC)) { + ztimer_sleep(ZTIMER_USEC, milliseconds); + } + else { + ztimer64_sleep(ZTIMER64_USEC, ((uint64_t)milliseconds) * 1000LLU); + } +} + +static inline void xtimer_usleep(uint32_t microseconds) +{ + ztimer_sleep(ZTIMER_USEC, microseconds); +} + +static inline void xtimer_nanosleep(uint32_t nanoseconds) +{ + ztimer_sleep(ZTIMER_USEC, nanoseconds / NS_PER_US); +} + +static inline void xtimer_set(xtimer_t *timer, uint32_t offset) +{ + ztimer64_set(ZTIMER64_USEC, timer, offset); +} + +static inline void xtimer_remove(xtimer_t *timer) +{ + ztimer64_remove(ZTIMER64_USEC, timer); +} + +static inline bool xtimer_is_set(const xtimer_t *timer) +{ + return ztimer64_is_set(timer); +} + +static inline void xtimer_set_msg(xtimer_t *timer, uint32_t offset, msg_t *msg, + kernel_pid_t target_pid) +{ + ztimer64_set_msg(ZTIMER64_USEC, timer, offset, msg, target_pid); +} + +static inline void xtimer_periodic_wakeup(xtimer_ticks32_t *last_wakeup, + uint32_t period) +{ + ztimer_periodic_wakeup(ZTIMER_USEC, last_wakeup, period); +} + +static inline uint32_t xtimer_usec_from_ticks(xtimer_ticks32_t ticks) +{ + return ticks; +} + +static inline xtimer_ticks32_t xtimer_ticks_from_usec(uint32_t usec) +{ + return usec; +} + +static inline void xtimer_now_timex(timex_t *out) +{ + uint64_t now = xtimer_now_usec64(); + + out->seconds = div_u64_by_1000000(now); + out->microseconds = now - (out->seconds * US_PER_SEC); +} + +static inline int xtimer_msg_receive_timeout(msg_t *msg, uint32_t timeout) +{ + return ztimer_msg_receive_timeout(ZTIMER_USEC, msg, timeout); +} + +static inline void xtimer_set_wakeup(xtimer_t *timer, uint32_t offset, + kernel_pid_t pid) +{ + ztimer64_set_wakeup(ZTIMER64_USEC, timer, offset, pid); +} + +static inline int xtimer_mutex_lock_timeout(mutex_t *mutex, uint64_t us) +{ + if (ztimer64_mutex_lock_timeout(ZTIMER64_USEC, mutex, us)) { + /* Impedance matching required: Convert -ECANCELED error code to -1: */ + return -1; + } + return 0; +} + +static inline int xtimer_rmutex_lock_timeout(rmutex_t *rmutex, uint64_t timeout) +{ + if (ztimer64_rmutex_lock_timeout(ZTIMER64_USEC, rmutex, timeout)) { + /* Impedance matching required: Convert -ECANCELED error code to -1: */ + return -1; + } + return 0; +} + +static inline void xtimer_set_timeout_flag64(xtimer_t *t, uint64_t timeout) +{ + ztimer64_set_timeout_flag(ZTIMER64_USEC, t, timeout); +} + +static inline void xtimer_set_timeout_flag(xtimer_t *t, uint32_t timeout) +{ + xtimer_set_timeout_flag64(t, timeout); +} + +static inline void xtimer_spin(xtimer_ticks32_t ticks) +{ + assert(ticks < US_PER_MS); + ztimer_now_t start = ztimer_now(ZTIMER_USEC); + + while (ztimer_now(ZTIMER_USEC) - start < ticks) { + /* busy waiting */ + } +} + +static inline xtimer_ticks32_t xtimer_diff(xtimer_ticks32_t a, + xtimer_ticks32_t b) +{ + return a - b; +} + +static inline xtimer_ticks64_t xtimer_diff64(xtimer_ticks64_t a, + xtimer_ticks64_t b) +{ + return a - b; +} + +static inline xtimer_ticks32_t xtimer_diff32_64(xtimer_ticks64_t a, + xtimer_ticks64_t b) +{ + return (xtimer_ticks32_t)(a - b); +} + +static inline xtimer_ticks64_t xtimer_ticks64(uint64_t ticks) +{ + return ticks; +} + +static inline bool xtimer_less(xtimer_ticks32_t a, xtimer_ticks32_t b) +{ + return a < b; +} + +static inline bool xtimer_less64(xtimer_ticks64_t a, xtimer_ticks64_t b) +{ + return a < b; +} + +static inline void xtimer_set64(xtimer_t *timer, uint64_t offset_us) +{ + ztimer64_set(ZTIMER64_USEC, timer, offset_us); +} + +static inline void xtimer_tsleep32(xtimer_ticks32_t ticks) +{ + ztimer_sleep(ZTIMER_USEC, ticks); +} + +static inline void xtimer_tsleep64(xtimer_ticks64_t ticks) +{ + ztimer64_sleep(ZTIMER64_USEC, ticks); +} + +static inline void xtimer_set_wakeup64(xtimer_t *timer, uint64_t offset, + kernel_pid_t pid) +{ + ztimer64_set_wakeup(ZTIMER64_USEC, timer, offset, pid); +} + +#if defined(MODULE_CORE_MSG) || defined(DOXYGEN) +static inline void xtimer_set_msg64(xtimer_t *timer, uint64_t offset, + msg_t *msg, kernel_pid_t target_pid) +{ + ztimer64_set_msg(ZTIMER64_USEC, timer, offset, msg, target_pid); +} + +static inline int xtimer_msg_receive_timeout64(msg_t *msg, uint64_t timeout) +{ + return ztimer64_msg_receive_timeout(ZTIMER64_SEC, msg, timeout); +} + +#endif + +#endif /* DOXYGEN */ + +#ifdef __cplusplus +} +#endif + +/** @} */ +#endif /* ZTIMER64_XTIMER_COMPAT_H */ diff --git a/sys/xtimer/Kconfig b/sys/xtimer/Kconfig index 8c6a8ab5e9..fdfeebb5b7 100644 --- a/sys/xtimer/Kconfig +++ b/sys/xtimer/Kconfig @@ -9,9 +9,8 @@ menuconfig MODULE_XTIMER bool "xtimer" depends on HAS_PERIPH_TIMER depends on TEST_KCONFIG - # use timer peripheral unless ztimer compatibility module is used - select MODULE_PERIPH_TIMER if HAS_PERIPH_TIMER && !MODULE_XTIMER_ON_ZTIMER && !MODULE_ZTIMER_XTIMER_COMPAT + select MODULE_PERIPH_TIMER if HAS_PERIPH_TIMER && !MODULE_XTIMER_ON_ZTIMER && !MODULE_ZTIMER_XTIMER_COMPAT && !MODULE_ZTIMER64_XTIMER_COMPAT select MODULE_DIV if !MODULE_ZTIMER_XTIMER_COMPAT help diff --git a/sys/ztimer/Kconfig b/sys/ztimer/Kconfig index 7ea3f78dd7..7483b1b230 100644 --- a/sys/ztimer/Kconfig +++ b/sys/ztimer/Kconfig @@ -141,11 +141,12 @@ menu "xtimer and evtimer compatibility" choice bool "xtimer compatibility" - depends on MODULE_XTIMER && MODULE_ZTIMER && MODULE_ZTIMER_PERIPH_TIMER + depends on MODULE_XTIMER && MODULE_ZTIMER config MODULE_XTIMER_ON_ZTIMER bool "ztimer_usec as timer backend for xtimer" select MODULE_ZTIMER_USEC + select MODULE_ZTIMER_PERIPH_TIMER config MODULE_ZTIMER_XTIMER_COMPAT bool "map xtimer calls to ztimer" @@ -155,15 +156,23 @@ config MODULE_ZTIMER_XTIMER_COMPAT This is a wrapper of xtimer API on ztimer_usec and is currently incomplete. Unless doing testing, use xtimer on ztimer. +comment "The ztimer xtimer compatibility module is incomplete, consider using MODULE_ZTIMER64_XTIMER_COMPAT instead." + depends on MODULE_ZTIMER_XTIMER_COMPAT + endchoice -comment "The ztimer xtimer compatibility module is incomplete, consider using MODULE_XTIMER_ON_ZTIMER instead." +config MODULE_ZTIMER64_XTIMER_COMPAT + bool "map xtimer calls to ztimer64" + select MODULE_DIV + select MODULE_ZTIMER64 + select MODULE_ZTIMER64_USEC depends on MODULE_ZTIMER_XTIMER_COMPAT + help + This is a wrapper of xtimer API on ztimer64_usec. config MODULE_EVTIMER_ON_ZTIMER bool "Use ztimer_msec as timer backend for evtimer" depends on MODULE_ZTIMER_MSEC - select MODULE_ZTIMER_NOW64 endmenu # xtimer compatibility diff --git a/sys/ztimer/Makefile.dep b/sys/ztimer/Makefile.dep index 009271e263..fdbfc39799 100644 --- a/sys/ztimer/Makefile.dep +++ b/sys/ztimer/Makefile.dep @@ -12,10 +12,12 @@ ifneq (,$(filter ztimer,$(USEMODULE))) endif # unless ztimer_xtimer_compat is used, make xtimer use ztimer_usec as backend. -ifneq (,$(filter ztimer_periph_timer,$(USEMODULE))) - ifneq (,$(filter xtimer,$(USEMODULE))) - ifeq (,$(filter ztimer_xtimer_compat,$(USEMODULE))) +ifneq (,$(filter ztimer,$(USEMODULE))) + ifneq (,$(filter xtimer,$(USEMODULE))) + ifeq (,$(filter ztimer_xtimer_compat ztimer64_xtimer_compat,$(USEMODULE))) USEMODULE += xtimer_on_ztimer + else + USEMODULE += div endif endif ifneq (,$(filter evtimer,$(USEMODULE))) @@ -23,6 +25,15 @@ ifneq (,$(filter ztimer_periph_timer,$(USEMODULE))) endif endif +ifneq (,$(filter ztimer_xtimer_compat,$(USEMODULE))) + USEMODULE += ztimer_usec +endif + +ifneq (,$(filter ztimer64_xtimer_compat,$(USEMODULE))) + USEMODULE += ztimer64_usec + USEMODULE += ztimer_xtimer_compat +endif + # make xtimer use ztimer_usec as low level timer ifneq (,$(filter xtimer_on_ztimer,$(USEMODULE))) USEMODULE += ztimer_usec @@ -33,13 +44,6 @@ ifneq (,$(filter evtimer_on_ztimer,$(USEMODULE))) USEMODULE += ztimer_msec endif -# "ztimer_xtimer_compat" is a wrapper of the xtimer API on ztimer_used -# (it is currently incomplete). Unless doing testing, use "xtimer_on_ztimer". -ifneq (,$(filter ztimer_xtimer_compat,$(USEMODULE))) - USEMODULE += div - USEMODULE += ztimer_usec -endif - ifneq (,$(filter ztimer_%,$(USEMODULE))) USEMODULE += ztimer_core USEMODULE += ztimer_extend