Merge pull request #13661 from jue89/feature/evtimer_on_ztimer

sys/evtimer: introduce ZTIMER_MSEC as timer backend
This commit is contained in:
Juergen Fitschen 2020-09-27 14:07:04 +02:00 committed by GitHub
commit 62fb4a2ade
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 81 additions and 15 deletions

View File

@ -737,10 +737,6 @@ ifneq (,$(filter phydat,$(USEMODULE)))
USEMODULE += fmt USEMODULE += fmt
endif endif
ifneq (,$(filter evtimer,$(USEMODULE)))
USEMODULE += xtimer
endif
ifneq (,$(filter evtimer_mbox,$(USEMODULE))) ifneq (,$(filter evtimer_mbox,$(USEMODULE)))
USEMODULE += evtimer USEMODULE += evtimer
USEMODULE += core_mbox USEMODULE += core_mbox
@ -1067,6 +1063,13 @@ ifneq (,$(filter ztimer% %ztimer,$(USEMODULE)))
include $(RIOTBASE)/sys/ztimer/Makefile.dep include $(RIOTBASE)/sys/ztimer/Makefile.dep
endif endif
# handle evtimer's deps. Needs to be done *after* ztimer
ifneq (,$(filter evtimer,$(USEMODULE)))
ifeq (,$(filter evtimer_on_ztimer,$(USEMODULE)))
USEMODULE += xtimer
endif
endif
# handle xtimer's deps. Needs to be done *after* ztimer # handle xtimer's deps. Needs to be done *after* ztimer
ifneq (,$(filter xtimer,$(USEMODULE))) ifneq (,$(filter xtimer,$(USEMODULE)))
ifeq (,$(filter ztimer_xtimer_compat,$(USEMODULE))) ifeq (,$(filter ztimer_xtimer_compat,$(USEMODULE)))

View File

@ -21,6 +21,7 @@ PSEUDOMODULES += dhcpv6_%
PSEUDOMODULES += ecc_% PSEUDOMODULES += ecc_%
PSEUDOMODULES += event_% PSEUDOMODULES += event_%
PSEUDOMODULES += evtimer_mbox PSEUDOMODULES += evtimer_mbox
PSEUDOMODULES += evtimer_on_ztimer
PSEUDOMODULES += fmt_% PSEUDOMODULES += fmt_%
PSEUDOMODULES += gnrc_dhcpv6_% PSEUDOMODULES += gnrc_dhcpv6_%
PSEUDOMODULES += gnrc_ipv6_default PSEUDOMODULES += gnrc_ipv6_default

View File

@ -24,7 +24,6 @@
#include "div.h" #include "div.h"
#include "irq.h" #include "irq.h"
#include "xtimer.h"
#include "evtimer.h" #include "evtimer.h"
@ -91,27 +90,57 @@ static void _del_event_from_list(evtimer_t *evtimer, evtimer_event_t *event)
} }
} }
static void _set_timer(xtimer_t *timer, uint32_t offset_ms) static void _set_timer(evtimer_t *evtimer)
{ {
uint64_t offset_us = (uint64_t)offset_ms * US_PER_MS; evtimer_event_t *next_event = evtimer->events;
#if IS_USED(MODULE_EVTIMER_ON_ZTIMER)
evtimer->base = ztimer_now(ZTIMER_MSEC);
DEBUG("evtimer: now=%" PRIu32 " ms setting ztimer to %" PRIu32 " ms\n",
evtimer->base, next_event->offset);
ztimer_set(ZTIMER_MSEC, &evtimer->timer, next_event->offset);
#else
uint64_t offset_us = (uint64_t)next_event->offset * US_PER_MS;
DEBUG("evtimer: now=%" PRIu32 " us setting xtimer to %" PRIu32 ":%" PRIu32 " us\n", DEBUG("evtimer: now=%" PRIu32 " us setting xtimer to %" PRIu32 ":%" PRIu32 " us\n",
xtimer_now_usec(), (uint32_t)(offset_us >> 32), (uint32_t)(offset_us)); xtimer_now_usec(), (uint32_t)(offset_us >> 32), (uint32_t)(offset_us));
xtimer_set64(timer, offset_us); xtimer_set64(&evtimer->timer, offset_us);
#endif
} }
static void _update_timer(evtimer_t *evtimer) static void _update_timer(evtimer_t *evtimer)
{ {
if (evtimer->events) { if (evtimer->events) {
evtimer_event_t *event = evtimer->events; _set_timer(evtimer);
_set_timer(&evtimer->timer, event->offset);
} }
else { else {
#if IS_USED(MODULE_EVTIMER_ON_ZTIMER)
ztimer_remove(ZTIMER_MSEC, &evtimer->timer);
#else
xtimer_remove(&evtimer->timer); xtimer_remove(&evtimer->timer);
#endif
} }
} }
#if IS_USED(MODULE_EVTIMER_ON_ZTIMER)
static void _update_head_offset(evtimer_t *evtimer)
{
if (evtimer->events) {
evtimer_event_t *event = evtimer->events;
uint32_t now = ztimer_now(ZTIMER_MSEC);
uint32_t elapsed = now - evtimer->base;
if (elapsed > event->offset) {
event->offset = 0;
} else {
event->offset -= elapsed;
}
evtimer->base = now;
}
}
#else /* IS_USED(MODULE_EVTIMER_ON_ZTIMER) */
static uint32_t _get_offset(xtimer_t *timer) static uint32_t _get_offset(xtimer_t *timer)
{ {
uint64_t left = xtimer_left_usec(timer); uint64_t left = xtimer_left_usec(timer);
@ -127,6 +156,7 @@ static void _update_head_offset(evtimer_t *evtimer)
DEBUG("evtimer: _update_head_offset(): new head offset %" PRIu32 "\n", event->offset); DEBUG("evtimer: _update_head_offset(): new head offset %" PRIu32 "\n", event->offset);
} }
} }
#endif /* !IS_USED(MODULE_EVTIMER_ON_ZTIMER) */
void evtimer_add(evtimer_t *evtimer, evtimer_event_t *event) void evtimer_add(evtimer_t *evtimer, evtimer_event_t *event)
{ {
@ -137,7 +167,7 @@ void evtimer_add(evtimer_t *evtimer, evtimer_event_t *event)
_update_head_offset(evtimer); _update_head_offset(evtimer);
_add_event_to_list(evtimer, event); _add_event_to_list(evtimer, event);
if (evtimer->events == event) { if (evtimer->events == event) {
_set_timer(&evtimer->timer, event->offset); _set_timer(evtimer);
} }
irq_restore(state); irq_restore(state);
if (sched_context_switch_request) { if (sched_context_switch_request) {

View File

@ -29,7 +29,9 @@
* the necessary fields, which can be extended as needed, and handlers define * the necessary fields, which can be extended as needed, and handlers define
* actions taken on timer triggers. Check out @ref evtimer_msg_event_t as * actions taken on timer triggers. Check out @ref evtimer_msg_event_t as
* example. * example.
* - uses @ref sys_xtimer "xtimer" as backend * - uses @ref sys_xtimer "xtimer" as backend by default. Alternatively, with
* the pseudomodule "evtimer_on_ztimer" compiled in, evtimer is backend by
* @ref sys_ztimer "ZTIMER_MSEC".
* *
* @{ * @{
* *
@ -44,8 +46,14 @@
#define EVTIMER_H #define EVTIMER_H
#include <stdint.h> #include <stdint.h>
#include "kernel_defines.h"
#if IS_USED(MODULE_EVTIMER_ON_ZTIMER)
#include "ztimer.h"
#else
#include "xtimer.h" #include "xtimer.h"
#endif
#include "timex.h" #include "timex.h"
#ifdef __cplusplus #ifdef __cplusplus
@ -69,7 +77,12 @@ typedef void(*evtimer_callback_t)(evtimer_event_t* event);
* @brief Event timer * @brief Event timer
*/ */
typedef struct { typedef struct {
#if IS_USED(MODULE_EVTIMER_ON_ZTIMER)
ztimer_t timer; /**< Timer */
uint32_t base; /**< Absolute time the first event is built on */
#else
xtimer_t timer; /**< Timer */ xtimer_t timer; /**< Timer */
#endif
evtimer_callback_t callback; /**< Handler function for this evtimer's evtimer_callback_t callback; /**< Handler function for this evtimer's
event type */ event type */
evtimer_event_t *events; /**< Event queue */ evtimer_event_t *events; /**< Event queue */
@ -115,7 +128,11 @@ void evtimer_print(const evtimer_t *evtimer);
*/ */
static inline uint32_t evtimer_now_msec(void) static inline uint32_t evtimer_now_msec(void)
{ {
#if IS_USED(MODULE_EVTIMER_ON_ZTIMER)
return ztimer_now(ZTIMER_MSEC);
#else
return xtimer_now_usec64() / US_PER_MS; return xtimer_now_usec64() / US_PER_MS;
#endif
} }
/** /**
@ -123,7 +140,11 @@ static inline uint32_t evtimer_now_msec(void)
*/ */
static inline uint32_t evtimer_now_min(void) static inline uint32_t evtimer_now_min(void)
{ {
#if IS_USED(MODULE_EVTIMER_ON_ZTIMER)
return ztimer_now(ZTIMER_MSEC) / (MS_PER_SEC * SEC_PER_MIN);
#else
return xtimer_now_usec64() / (US_PER_SEC * SEC_PER_MIN); return xtimer_now_usec64() / (US_PER_SEC * SEC_PER_MIN);
#endif
} }
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -21,6 +21,7 @@
#ifndef NET_GNRC_MAC_TIMEOUT_H #ifndef NET_GNRC_MAC_TIMEOUT_H
#define NET_GNRC_MAC_TIMEOUT_H #define NET_GNRC_MAC_TIMEOUT_H
#include <assert.h>
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>

View File

@ -30,6 +30,9 @@ ifneq (,$(filter ztimer_periph_timer,$(USEMODULE)))
USEMODULE += xtimer_on_ztimer USEMODULE += xtimer_on_ztimer
endif endif
endif endif
ifneq (,$(filter evtimer,$(USEMODULE)))
USEMODULE += evtimer_on_ztimer
endif
endif endif
# make xtimer use ztimer_usec as low level timer # make xtimer use ztimer_usec as low level timer
@ -37,6 +40,12 @@ ifneq (,$(filter xtimer_on_ztimer,$(USEMODULE)))
USEMODULE += ztimer_usec USEMODULE += ztimer_usec
endif endif
# make evtimer use ztimer_msec as low level timer
ifneq (,$(filter evtimer_on_ztimer,$(USEMODULE)))
USEMODULE += ztimer_msec
USEMODULE += ztimer_now64
endif
# "ztimer_xtimer_compat" is a wrapper of the xtimer API on ztimer_used # "ztimer_xtimer_compat" is a wrapper of the xtimer API on ztimer_used
# (it is currently incomplete). Unless doing testing, use "xtimer_on_ztimer". # (it is currently incomplete). Unless doing testing, use "xtimer_on_ztimer".
ifneq (,$(filter ztimer_xtimer_compat,$(USEMODULE))) ifneq (,$(filter ztimer_xtimer_compat,$(USEMODULE)))

View File

@ -1,6 +1,7 @@
include ../Makefile.tests_common include ../Makefile.tests_common
USEMODULE += evtimer USEMODULE += evtimer
USEMODULE += xtimer
# This test randomly fails on `native` so disable it from CI # This test randomly fails on `native` so disable it from CI
TEST_ON_CI_BLACKLIST += native TEST_ON_CI_BLACKLIST += native

View File

@ -54,7 +54,7 @@ void *worker_thread(void *arg)
uint32_t now; uint32_t now;
msg_receive(&m); msg_receive(&m);
now = xtimer_now_usec() / US_PER_MS; now = evtimer_now_msec();
ctx = m.content.ptr; ctx = m.content.ptr;
printf("At %6" PRIu32 " ms received msg %i: \"%s\"\n", now, count++, ctx); printf("At %6" PRIu32 " ms received msg %i: \"%s\"\n", now, count++, ctx);
} }
@ -77,7 +77,7 @@ int main(void)
/* Add all the events */ /* Add all the events */
for (unsigned i = 0; i < NEVENTS; i++) { for (unsigned i = 0; i < NEVENTS; i++) {
events[i].event.offset = offsets[i]; events[i].event.offset = offsets[i];
now = xtimer_now_usec() / US_PER_MS; now = evtimer_now_msec();
snprintf(texts[i], sizeof(texts[i]) - 1, "#%u supposed to be %" PRIu32, i, now + events[i].event.offset); snprintf(texts[i], sizeof(texts[i]) - 1, "#%u supposed to be %" PRIu32, i, now + events[i].event.offset);
events[i].msg.content.ptr = texts[i]; events[i].msg.content.ptr = texts[i];
evtimer_add_msg(&evtimer, &events[i], pid); evtimer_add_msg(&evtimer, &events[i], pid);
@ -99,7 +99,7 @@ int main(void)
/* Add all the events, again */ /* Add all the events, again */
for (unsigned i = 0; i < NEVENTS; i++) { for (unsigned i = 0; i < NEVENTS; i++) {
events[i].event.offset = offsets[i]; events[i].event.offset = offsets[i];
now = xtimer_now_usec() / US_PER_MS; now = evtimer_now_msec();
snprintf(texts[i], sizeof(texts[i]) - 1, "#%u supposed to be %" PRIu32, i, now + events[i].event.offset); snprintf(texts[i], sizeof(texts[i]) - 1, "#%u supposed to be %" PRIu32, i, now + events[i].event.offset);
events[i].msg.content.ptr = texts[i]; events[i].msg.content.ptr = texts[i];
evtimer_add_msg(&evtimer, &events[i], pid); evtimer_add_msg(&evtimer, &events[i], pid);