From 387344775bc0d7cb14fd0f9517e1e7faae6c266b Mon Sep 17 00:00:00 2001 From: Hyungsin Date: Thu, 9 Jan 2020 14:34:43 -0800 Subject: [PATCH 01/11] sys: xtimer concurrency/robustness improvement --- sys/include/xtimer.h | 64 +--- sys/include/xtimer/implementation.h | 37 +- sys/xtimer/xtimer.c | 104 ++---- sys/xtimer/xtimer_core.c | 561 ++++++++-------------------- 4 files changed, 203 insertions(+), 563 deletions(-) diff --git a/sys/include/xtimer.h b/sys/include/xtimer.h index 61648f9f10a9..aea20cc02972 100644 --- a/sys/include/xtimer.h +++ b/sys/include/xtimer.h @@ -73,8 +73,10 @@ typedef void (*xtimer_callback_t)(void*); */ typedef struct xtimer { struct xtimer *next; /**< reference to next timer in timer lists */ - uint32_t target; /**< lower 32bit absolute target time */ - uint32_t long_target; /**< upper 32bit absolute target time */ + uint32_t offset; /**< lower 32bit offset time */ + uint32_t long_offset; /**< upper 32bit offset time */ + uint32_t start_time; /**< lower 32bit absolute start time */ + uint32_t long_start_time; /**< upper 32bit absolute start time */ xtimer_callback_t callback; /**< callback function to call when timer expires */ void *arg; /**< argument to pass to callback function */ @@ -218,8 +220,6 @@ static inline void xtimer_periodic_wakeup(xtimer_ticks32_t *last_wakeup, uint32_ * expired. * * @param[in] timer timer struct to work with. - * Its xtimer_t::target and xtimer_t::long_target - * fields need to be initialized with 0 on first use * @param[in] offset microseconds from now * @param[in] pid pid of the thread that will be woken up */ @@ -232,8 +232,6 @@ static inline void xtimer_set_wakeup(xtimer_t *timer, uint32_t offset, kernel_pi * expired. * * @param[in] timer timer struct to work with. - * Its xtimer_t::target and xtimer_t::long_target - * fields need to be initialized with 0 on first use * @param[in] offset microseconds from now * @param[in] pid pid of the thread that will be woken up */ @@ -252,8 +250,6 @@ static inline void xtimer_set_wakeup64(xtimer_t *timer, uint64_t offset, kernel_ * know *exactly* what that means. * * @param[in] timer the timer structure to use. - * Its xtimer_t::target and xtimer_t::long_target - * fields need to be initialized with 0 on first use * @param[in] offset time in microseconds from now specifying that timer's * callback's execution time */ @@ -273,8 +269,6 @@ static inline void xtimer_set(xtimer_t *timer, uint32_t offset); * know *exactly* what that means. * * @param[in] timer the timer structure to use. - * Its xtimer_t::target and xtimer_t::long_target - * fields need to be initialized with 0 on first use * @param[in] offset_us time in microseconds from now specifying that timer's * callback's execution time */ @@ -426,8 +420,6 @@ void xtimer_set_timeout_flag(xtimer_t *t, uint32_t timeout); * needs to point to valid memory until the message has been delivered. * * @param[in] timer timer struct to work with. - * Its xtimer_t::target and xtimer_t::long_target - * fields need to be initialized with 0 on first use. * @param[in] offset microseconds from now * @param[in] msg ptr to msg that will be sent * @param[in] target_pid pid the message will be sent to @@ -444,8 +436,6 @@ static inline void xtimer_set_msg(xtimer_t *timer, uint32_t offset, msg_t *msg, * needs to point to valid memory until the message has been delivered. * * @param[in] timer timer struct to work with. - * Its xtimer_t::target and xtimer_t::long_target - * fields need to be initialized with 0 on first use. * @param[in] offset microseconds from now * @param[in] msg ptr to msg that will be sent * @param[in] target_pid pid the message will be sent to @@ -487,29 +477,6 @@ static inline int xtimer_msg_receive_timeout64(msg_t *msg, uint64_t timeout); #define XTIMER_BACKOFF 30 #endif -/** - * @brief xtimer overhead value, in hardware ticks - * - * This value specifies the time a timer will be late if uncorrected, e.g., - * the system-specific xtimer execution time from timer ISR to executing - * a timer's callback's first instruction. - * - * E.g., with XTIMER_OVERHEAD == 0 - * start=xtimer_now(); - * xtimer_set(&timer, X); - * (in callback:) - * overhead=xtimer_now()-start-X; - * - * xtimer automatically subtracts XTIMER_OVERHEAD from a timer's target time, - * but when the timer triggers, xtimer will spin-lock until a timer's target - * time is reached, so timers will never trigger early. - * - * This is supposed to be defined per-device in e.g., periph_conf.h. - */ -#ifndef XTIMER_OVERHEAD -#define XTIMER_OVERHEAD 20 -#endif - #ifndef XTIMER_ISR_BACKOFF /** * @brief xtimer IRQ backoff time, in hardware ticks @@ -522,29 +489,6 @@ static inline int xtimer_msg_receive_timeout64(msg_t *msg, uint64_t timeout); #define XTIMER_ISR_BACKOFF 20 #endif -#ifndef XTIMER_PERIODIC_SPIN -/** - * @brief xtimer_periodic_wakeup spin cutoff - * - * If the difference between target time and now is less than this value, then - * xtimer_periodic_wakeup will use xtimer_spin instead of setting a timer. - */ -#define XTIMER_PERIODIC_SPIN (XTIMER_BACKOFF * 2) -#endif - -#ifndef XTIMER_PERIODIC_RELATIVE -/** - * @brief xtimer_periodic_wakeup relative target cutoff - * - * If the difference between target time and now is less than this value, then - * xtimer_periodic_wakeup will set a relative target time in the future instead - * of the true target. - * - * This is done to prevent target time underflows. - */ -#define XTIMER_PERIODIC_RELATIVE (512) -#endif - /* * Default xtimer configuration */ diff --git a/sys/include/xtimer/implementation.h b/sys/include/xtimer/implementation.h index 4c791240ceec..9006252db641 100644 --- a/sys/include/xtimer/implementation.h +++ b/sys/include/xtimer/implementation.h @@ -28,14 +28,13 @@ #endif #include "periph/timer.h" +#include "irq.h" #ifdef __cplusplus extern "C" { #endif -#if XTIMER_MASK -extern volatile uint32_t _xtimer_high_cnt; -#endif +extern volatile uint64_t _xtimer_current_time; /** * @brief IPC message type for xtimer msg callback @@ -66,7 +65,7 @@ static inline uint32_t _xtimer_lltimer_mask(uint32_t val) * @internal */ -uint64_t _xtimer_now64(void); +uint32_t _xtimer_now(void); /** * @brief Sets the timer to the appropriate timer_list or list_head. @@ -81,7 +80,6 @@ uint64_t _xtimer_now64(void); * @param[in] target Absolute target value in ticks. */ int _xtimer_set_absolute(xtimer_t *timer, uint32_t target); -void _xtimer_set(xtimer_t *timer, uint32_t offset); void _xtimer_set64(xtimer_t *timer, uint32_t offset, uint32_t long_offset); void _xtimer_periodic_wakeup(uint32_t *last_wakeup, uint32_t period); void _xtimer_set_wakeup(xtimer_t *timer, uint32_t offset, kernel_pid_t pid); @@ -109,24 +107,23 @@ void _xtimer_tsleep(uint32_t offset, uint32_t long_offset); #ifndef DOXYGEN /* Doxygen warns that these are undocumented, but the documentation can be found in xtimer.h */ -static inline uint32_t _xtimer_now(void) +static inline uint64_t _xtimer_now64(void) { -#if XTIMER_MASK - uint32_t latched_high_cnt, now; - - /* _high_cnt can change at any time, so check the value before - * and after reading the low-level timer. If it hasn't changed, - * then it can be safely applied to the timer count. */ + uint32_t now, elapsed; - do { - latched_high_cnt = _xtimer_high_cnt; - now = _xtimer_lltimer_now(); - } while (_xtimer_high_cnt != latched_high_cnt); - - return latched_high_cnt | now; + /* time sensitive since _xtimer_current_time is updated here */ + uint8_t state = irq_disable(); + now = _xtimer_lltimer_now(); +#if XTIMER_MASK + elapsed = _xtimer_lltimer_mask(now - _xtimer_lltimer_mask((uint32_t)_xtimer_current_time)); + _xtimer_current_time += (uint64_t)elapsed; #else - return _xtimer_lltimer_now(); + elapsed = now - ((uint32_t)_xtimer_current_time & 0xFFFFFFFF); + _xtimer_current_time += (uint64_t)elapsed; #endif + irq_restore(state); + + return _xtimer_current_time; } static inline xtimer_ticks32_t xtimer_now(void) @@ -224,7 +221,7 @@ static inline void xtimer_set_wakeup64(xtimer_t *timer, uint64_t offset, kernel_ static inline void xtimer_set(xtimer_t *timer, uint32_t offset) { - _xtimer_set(timer, _xtimer_ticks_from_usec(offset)); + _xtimer_set64(timer, _xtimer_ticks_from_usec(offset), 0); } static inline void xtimer_set64(xtimer_t *timer, uint64_t period_us) diff --git a/sys/xtimer/xtimer.c b/sys/xtimer/xtimer.c index 2aa55bd83909..17cdf2165753 100644 --- a/sys/xtimer/xtimer.c +++ b/sys/xtimer/xtimer.c @@ -67,7 +67,6 @@ void _xtimer_tsleep(uint32_t offset, uint32_t long_offset) timer.callback = _callback_unlock_mutex; timer.arg = (void*) &mutex; - timer.target = timer.long_target = 0; mutex_lock(&mutex); _xtimer_set64(&timer, offset, long_offset); @@ -81,62 +80,24 @@ void _xtimer_periodic_wakeup(uint32_t *last_wakeup, uint32_t period) { timer.callback = _callback_unlock_mutex; timer.arg = (void*) &mutex; - uint32_t target = (*last_wakeup) + period; + /* time sensitive until setting offset */ + unsigned int state = irq_disable(); uint32_t now = _xtimer_now(); - /* make sure we're not setting a value in the past */ - if (now < (*last_wakeup)) { - /* base timer overflowed between last_wakeup and now */ - if (!((now < target) && (target < (*last_wakeup)))) { - /* target time has already passed */ - goto out; - } - } - else { - /* base timer did not overflow */ - if ((((*last_wakeup) <= target) && (target <= now))) { - /* target time has already passed */ - goto out; - } - } + uint32_t elapsed = now - (*last_wakeup); + uint32_t offset = (*last_wakeup) + period - now; + irq_restore(state); - /* - * For large offsets, set an absolute target time. - * As that might cause an underflow, for small offsets, set a relative - * target time. - * For very small offsets, spin. - */ - /* - * Note: last_wakeup _must never_ specify a time in the future after - * _xtimer_periodic_sleep returns. - * If this happens, last_wakeup may specify a time in the future when the - * next call to _xtimer_periodic_sleep is made, which in turn will trigger - * the overflow logic above and make the next timer fire too early, causing - * last_wakeup to point even further into the future, leading to a chain - * reaction. - * - * tl;dr Don't return too early! - */ - uint32_t offset = target - now; - DEBUG("xps, now: %9" PRIu32 ", tgt: %9" PRIu32 ", off: %9" PRIu32 "\n", now, target, offset); - if (offset < XTIMER_PERIODIC_SPIN) { - _xtimer_spin(offset); - } - else { - if (offset < XTIMER_PERIODIC_RELATIVE) { - /* NB: This will overshoot the target by the amount of time it took - * to get here from the beginning of xtimer_periodic_wakeup() - * - * Since interrupts are normally enabled inside this function, this time may - * be undeterministic. */ - target = _xtimer_now() + offset; - } - mutex_lock(&mutex); - DEBUG("xps, abs: %" PRIu32 "\n", target); - _xtimer_set_absolute(&timer, target); - mutex_lock(&mutex); + if (elapsed >= period) { + /* timer should be fired right now (some time drift might happen) */ + *last_wakeup = now; + return; } -out: - *last_wakeup = target; + + mutex_lock(&mutex); + _xtimer_set64(&timer, offset, 0); + mutex_lock(&mutex); + + *last_wakeup = now + offset; } #ifdef MODULE_CORE_MSG @@ -158,7 +119,7 @@ static inline void _setup_msg(xtimer_t *timer, msg_t *msg, kernel_pid_t target_p void _xtimer_set_msg(xtimer_t *timer, uint32_t offset, msg_t *msg, kernel_pid_t target_pid) { _setup_msg(timer, msg, target_pid); - _xtimer_set(timer, offset); + _xtimer_set64(timer, offset, 0); } void _xtimer_set_msg64(xtimer_t *timer, uint64_t offset, msg_t *msg, kernel_pid_t target_pid) @@ -175,7 +136,7 @@ static void _setup_timer_msg(msg_t *m, xtimer_t *t) m->type = MSG_XTIMER; m->content.ptr = m; - t->target = t->long_target = 0; + t->offset = t->long_offset = 0; } /* Waits for incoming message or timeout. */ @@ -220,7 +181,7 @@ void _xtimer_set_wakeup(xtimer_t *timer, uint32_t offset, kernel_pid_t pid) timer->callback = _callback_wakeup; timer->arg = (void*) ((intptr_t)pid); - _xtimer_set(timer, offset); + _xtimer_set64(timer, offset, 0); } void _xtimer_set_wakeup64(xtimer_t *timer, uint64_t offset, kernel_pid_t pid) @@ -248,26 +209,23 @@ static void _mutex_timeout(void *arg) * If the xtimer spin is fixed in the future * interups disable/restore can be removed */ - unsigned irqstate = irq_disable(); + unsigned int irqstate = irq_disable(); mutex_thread_t *mt = (mutex_thread_t *)arg; - if (mt->mutex->queue.next != MUTEX_LOCKED && - mt->mutex->queue.next != NULL) { - mt->timeout = 1; - list_node_t *node = list_remove(&mt->mutex->queue, - (list_node_t *)&mt->thread->rq_entry); - - /* if thread was removed from the list */ - if (node != NULL) { - if (mt->mutex->queue.next == NULL) { - mt->mutex->queue.next = MUTEX_LOCKED; - } - sched_set_status(mt->thread, STATUS_PENDING); - irq_restore(irqstate); - sched_switch(mt->thread->priority); - return; + mt->timeout = 1; + list_node_t *node = list_remove(&mt->mutex->queue, + (list_node_t *)&mt->thread->rq_entry); + + /* if thread was removed from the list */ + if (node != NULL) { + if (mt->mutex->queue.next == NULL) { + mt->mutex->queue.next = MUTEX_LOCKED; } + sched_set_status(mt->thread, STATUS_PENDING); + irq_restore(irqstate); + sched_switch(mt->thread->priority); + return; } irq_restore(irqstate); } diff --git a/sys/xtimer/xtimer_core.c b/sys/xtimer/xtimer_core.c index de140d7fd5c5..3542b30727de 100644 --- a/sys/xtimer/xtimer_core.c +++ b/sys/xtimer/xtimer_core.c @@ -2,6 +2,7 @@ * Copyright (C) 2015 Kaspar Schleiser * 2016 Eistec AB * 2018 Josua Arndt + * 2018 UC Berkeley * * 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 @@ -17,6 +18,7 @@ * @author Kaspar Schleiser * @author Joakim NohlgÄrd * @author Josua Arndt + * @author Hyung-Sin Kim * @} */ @@ -35,123 +37,74 @@ static volatile int _in_handler = 0; -static volatile uint32_t _long_cnt = 0; -#if XTIMER_MASK -volatile uint32_t _xtimer_high_cnt = 0; -#endif - -static inline void xtimer_spin_until(uint32_t value); +volatile uint64_t _xtimer_current_time = 0; static xtimer_t *timer_list_head = NULL; -static xtimer_t *overflow_list_head = NULL; static xtimer_t *long_list_head = NULL; +static bool _lltimer_ongoing = false; static void _add_timer_to_list(xtimer_t **list_head, xtimer_t *timer); -static void _add_timer_to_long_list(xtimer_t **list_head, xtimer_t *timer); static void _shoot(xtimer_t *timer); -static void _remove(xtimer_t *timer); -static inline void _lltimer_set(uint32_t target); -static uint32_t _time_left(uint32_t target, uint32_t reference); +static inline void _update_short_timers(uint64_t *now); +static inline void _update_long_timers(uint64_t *now); +static inline void _schedule_earliest_lltimer(uint32_t now); static void _timer_callback(void); static void _periph_timer_callback(void *arg, int chan); -static inline int _this_high_period(uint32_t target); - -static inline int _is_set(xtimer_t *timer) -{ - return (timer->target || timer->long_target); -} - -static inline void xtimer_spin_until(uint32_t target) -{ -#if XTIMER_MASK - target = _xtimer_lltimer_mask(target); -#endif - while (_xtimer_lltimer_now() > target) {} - while (_xtimer_lltimer_now() < target) {} -} - void xtimer_init(void) { /* initialize low-level timer */ timer_init(XTIMER_DEV, XTIMER_HZ, _periph_timer_callback, NULL); /* register initial overflow tick */ - _lltimer_set(0xFFFFFFFF); + _schedule_earliest_lltimer(_xtimer_now()); } -static void _xtimer_now_internal(uint32_t *short_term, uint32_t *long_term) +uint32_t _xtimer_now(void) { - uint32_t before, after, long_value; - - /* loop to cope with possible overflow of _xtimer_now() */ - do { - before = _xtimer_now(); - long_value = _long_cnt; - after = _xtimer_now(); - - } while (before > after); - - *short_term = after; - *long_term = long_value; -} - -uint64_t _xtimer_now64(void) -{ - uint32_t short_term, long_term; - - _xtimer_now_internal(&short_term, &long_term); - - return ((uint64_t)long_term << 32) + short_term; + return (uint32_t) _xtimer_now64(); } void _xtimer_set64(xtimer_t *timer, uint32_t offset, uint32_t long_offset) { DEBUG(" _xtimer_set64() offset=%" PRIu32 " long_offset=%" PRIu32 "\n", offset, long_offset); - if (!long_offset) { - /* timer fits into the short timer */ - _xtimer_set(timer, (uint32_t)offset); - } - else { - int state = irq_disable(); - if (_is_set(timer)) { - _remove(timer); - } - _xtimer_now_internal(&timer->target, &timer->long_target); - timer->target += offset; - timer->long_target += long_offset; - if (timer->target < offset) { - timer->long_target++; - } - - _add_timer_to_long_list(&long_list_head, timer); - irq_restore(state); - DEBUG("xtimer_set64(): added longterm timer (long_target=%" PRIu32 " target=%" PRIu32 ")\n", - timer->long_target, timer->target); - } -} - -void _xtimer_set(xtimer_t *timer, uint32_t offset) -{ - DEBUG("timer_set(): offset=%" PRIu32 " now=%" PRIu32 " (%" PRIu32 ")\n", - offset, xtimer_now().ticks32, _xtimer_lltimer_now()); if (!timer->callback) { - DEBUG("timer_set(): timer has no callback.\n"); + DEBUG("_xtimer_set64(): timer has no callback.\n"); return; } xtimer_remove(timer); - if (offset < XTIMER_BACKOFF) { + if (!long_offset && offset < XTIMER_BACKOFF) { + /* timer fits into the short timer */ _xtimer_spin(offset); _shoot(timer); + return; + } + + /* time sensitive */ + unsigned int state = irq_disable(); + uint64_t now = _xtimer_now64(); + timer->offset = offset; + timer->long_offset = long_offset; + timer->start_time = (uint32_t)now; + timer->long_start_time = (uint32_t)(now >> 32); + + if (!long_offset) { + _add_timer_to_list(&timer_list_head, timer); + + if (timer_list_head == timer) { + DEBUG("_xtimer_set64(): timer is new list head. updating lltimer.\n"); + _schedule_earliest_lltimer((uint32_t)now); + } } else { - uint32_t target = _xtimer_now() + offset; - _xtimer_set_absolute(timer, target); + _add_timer_to_list(&long_list_head, timer); + DEBUG("_xtimer_set64(): added longterm timer.\n"); } + irq_restore(state); } static void _periph_timer_callback(void *arg, int chan) @@ -166,107 +119,56 @@ static void _shoot(xtimer_t *timer) timer->callback(timer->arg); } -static inline void _lltimer_set(uint32_t target) +static inline void _schedule_earliest_lltimer(uint32_t now) { + uint32_t target; + if (_in_handler) { return; } - DEBUG("_lltimer_set(): setting %" PRIu32 "\n", _xtimer_lltimer_mask(target)); - timer_set_absolute(XTIMER_DEV, XTIMER_CHAN, _xtimer_lltimer_mask(target)); -} - -int _xtimer_set_absolute(xtimer_t *timer, uint32_t target) -{ - uint32_t now = _xtimer_now(); - int res = 0; - - timer->next = NULL; - - /* Ensure that offset is bigger than 'XTIMER_BACKOFF', - * 'target - now' will always be the offset no matter if target < or > now. - * - * This expects that target was not set too close to now and overrun now, so - * from setting target up until the call of '_xtimer_now()' above now has not - * become equal or bigger than target. - * This is crucial when using low CPU frequencies so reaching the '_xtimer_now()' - * call needs multiple xtimer ticks. - * - * '_xtimer_set()' and `_xtimer_periodic_wakeup()` ensure this by already - * backing off for small values. */ - uint32_t offset = (target - now); - - DEBUG("timer_set_absolute(): now=%" PRIu32 " target=%" PRIu32 " offset=%" PRIu32 "\n", - now, target, offset); - - if (offset <= XTIMER_BACKOFF) { - /* backoff */ - xtimer_spin_until(target); - _shoot(timer); - return 0; - } - unsigned state = irq_disable(); - if (_is_set(timer)) { - _remove(timer); + if (timer_list_head && timer_list_head->offset <= (_xtimer_lltimer_mask(0xFFFFFFFF)>>1)) { + /* schedule lltimer on next timer target time */ + target = timer_list_head->start_time + timer_list_head->offset; } - - timer->target = target; - timer->long_target = _long_cnt; - - /* Ensure timer is fired in right timer period. - * Backoff condition above ensures that 'target - XTIMER_OVERHEAD` is later - * than 'now', also for values when now will overflow and the value of target - * is smaller then now. - * If `target < XTIMER_OVERHEAD` the new target will be at the end of this - * 32bit period, as `target - XTIMER_OVERHEAD` is a big number instead of a - * small at the beginning of the next period. */ - target = target - XTIMER_OVERHEAD; - - /* 32 bit target overflow, target is in next 32bit period */ - if (target < now) { - timer->long_target++; - } - - if ((timer->long_target > _long_cnt) || !_this_high_period(target)) { - DEBUG("xtimer_set_absolute(): the timer doesn't fit into the low-level timer's mask.\n"); - _add_timer_to_long_list(&long_list_head, timer); + else if (!_lltimer_ongoing) { + /* schedule lltimer after max_low_level_time/2 to detect a cycle */ + target = now + (_xtimer_lltimer_mask(0xFFFFFFFF)>>1); } else { - if (_xtimer_lltimer_mask(now) >= target) { - DEBUG("xtimer_set_absolute(): the timer will expire in the next timer period\n"); - _add_timer_to_list(&overflow_list_head, timer); - } - else { - DEBUG("timer_set_absolute(): timer will expire in this timer period.\n"); - _add_timer_to_list(&timer_list_head, timer); - - if (timer_list_head == timer) { - DEBUG("timer_set_absolute(): timer is new list head. updating lltimer.\n"); - _lltimer_set(target); - } - } + /* lltimer is already running */ + return; } - irq_restore(state); - - return res; + DEBUG("_schedule_earliest_lltimer(): setting %" PRIu32 "\n", _xtimer_lltimer_mask(target)); + timer_set_absolute(XTIMER_DEV, XTIMER_CHAN, _xtimer_lltimer_mask(target)); + _lltimer_ongoing = true; } -static void _add_timer_to_list(xtimer_t **list_head, xtimer_t *timer) +/** + * @brief compare two timers. return true if timerA expires earlier than or equal to timerB and false otherwise. + */ +static bool _timer_comparison(xtimer_t* timerA, xtimer_t* timerB) { - while (*list_head && (*list_head)->target <= timer->target) { - list_head = &((*list_head)->next); + if (timerA->long_offset < timerB->long_offset) { + return true; } - - timer->next = *list_head; - *list_head = timer; + if (timerA->long_offset == timerB->long_offset + /* this condition is needed for when timerA was already expired before timerB starts */ + && (timerA->start_time + timerA->offset < timerB->start_time + /* it is necessary to compare two offsets, instead of two absolute times */ + || timerA->start_time + timerA->offset - timerB->start_time <= timerB->offset)) { + return true; + } + return false; } -static void _add_timer_to_long_list(xtimer_t **list_head, xtimer_t *timer) +/** + * @brief add a timer to an ordered list of timers + */ +static void _add_timer_to_list(xtimer_t **list_head, xtimer_t *timer) { - while (*list_head - && (((*list_head)->long_target < timer->long_target) - || (((*list_head)->long_target == timer->long_target) && ((*list_head)->target <= timer->target)))) { + while (*list_head && _timer_comparison((*list_head), timer)) { list_head = &((*list_head)->next); } @@ -274,300 +176,139 @@ static void _add_timer_to_long_list(xtimer_t **list_head, xtimer_t *timer) *list_head = timer; } -static int _remove_timer_from_list(xtimer_t **list_head, xtimer_t *timer) +/** + * @brief remove a timer from an ordered list of timers + */ +static void _remove_timer_from_list(xtimer_t **list_head, xtimer_t *timer) { while (*list_head) { if (*list_head == timer) { *list_head = timer->next; - return 1; + timer->next = NULL; + return; } list_head = &((*list_head)->next); } - - return 0; -} - -static void _remove(xtimer_t *timer) -{ - if (timer_list_head == timer) { - uint32_t next; - timer_list_head = timer->next; - if (timer_list_head) { - /* schedule callback on next timer target time */ - next = timer_list_head->target - XTIMER_OVERHEAD; - } - else { - next = _xtimer_lltimer_mask(0xFFFFFFFF); - } - _lltimer_set(next); - } - else { - if (!_remove_timer_from_list(&timer_list_head, timer)) { - if (!_remove_timer_from_list(&overflow_list_head, timer)) { - _remove_timer_from_list(&long_list_head, timer); - } - } - } } void xtimer_remove(xtimer_t *timer) { - int state = irq_disable(); - - if (_is_set(timer)) { - _remove(timer); - } + /* time sensitive since the target timer can be fired */ + unsigned int state = irq_disable(); + timer->offset = 0; + timer->long_offset = 0; + timer->start_time = 0; + timer->long_start_time = 0; + + _remove_timer_from_list(&timer_list_head, timer); + _remove_timer_from_list(&long_list_head, timer); irq_restore(state); } -static uint32_t _time_left(uint32_t target, uint32_t reference) -{ - uint32_t now = _xtimer_lltimer_now(); - - if (now < reference) { - return 0; - } - - if (target > now) { - return target - now; - } - else { - return 0; - } -} - -static inline int _this_high_period(uint32_t target) -{ -#if XTIMER_MASK - return (target & XTIMER_MASK) == _xtimer_high_cnt; -#else - (void)target; - return 1; -#endif -} - -/** - * @brief compare two timers' target values, return the one with lower value. - * - * if either is NULL, return the other. - * if both are NULL, return NULL. - */ -static inline xtimer_t *_compare(xtimer_t *a, xtimer_t *b) -{ - if (a && b) { - return ((a->target <= b->target) ? a : b); - } - else { - return (a ? a : b); - } -} - /** - * @brief merge two timer lists, return head of new list + * @brief update long timers' offsets and switch those that will expire in + * one short timer period to the short timer list */ -static xtimer_t *_merge_lists(xtimer_t *head_a, xtimer_t *head_b) +static inline void _update_long_timers(uint64_t *now) { - xtimer_t *result_head = _compare(head_a, head_b); - xtimer_t *pos = result_head; - - while (1) { - head_a = head_a->next; - head_b = head_b->next; - if (!head_a) { - pos->next = head_b; - break; - } - if (!head_b) { - pos->next = head_a; - break; - } + xtimer_t *timer = long_list_head; - pos->next = _compare(head_a, head_b); - pos = pos->next; - } + while (timer) { + uint32_t elapsed = (uint32_t)*now - timer->start_time; - return result_head; -} - -/** - * @brief parse long timers list and copy those that will expire in the current - * short timer period - */ -static void _select_long_timers(void) -{ - xtimer_t *select_list_start = long_list_head; - xtimer_t *select_list_last = NULL; - - /* advance long_list head so it points to the first timer of the next (not - * just started) "long timer period" */ - while (long_list_head) { - if ((long_list_head->long_target <= _long_cnt) && _this_high_period(long_list_head->target)) { - select_list_last = long_list_head; - long_list_head = long_list_head->next; - } - else { - /* remaining long_list timers belong to later long periods */ - break; + if (timer->offset < elapsed) { + timer->long_offset--; } - } + timer->offset -= elapsed; + timer->start_time = (uint32_t)*now; + timer->long_start_time = (uint32_t)(*now >> 32); - /* cut the "selected long timer list" at the end */ - if (select_list_last) { - select_list_last->next = NULL; - } + if (!timer->long_offset) { + assert(timer == long_list_head); - /* merge "current timer list" and "selected long timer list" */ - if (timer_list_head) { - if (select_list_last) { - /* both lists are non-empty. merge. */ - timer_list_head = _merge_lists(timer_list_head, select_list_start); + _remove_timer_from_list(&long_list_head, timer); + _add_timer_to_list(&timer_list_head, timer); + timer = long_list_head; } else { - /* "selected long timer list" is empty, nothing to do */ - } - } - else { /* current timer list is empty */ - if (select_list_last) { - /* there's no current timer list, but a non-empty "selected long - * timer list". So just use that list as the new current timer - * list.*/ - timer_list_head = select_list_start; + timer = timer->next; } } } /** - * @brief handle low-level timer overflow, advance to next short timer period + * @brief update short timers' offsets and fire those that are close to expiry */ -static void _next_period(void) +static inline void _update_short_timers(uint64_t *now) { -#if XTIMER_MASK - /* advance <32bit mask register */ - _xtimer_high_cnt += ~XTIMER_MASK + 1; - if (_xtimer_high_cnt == 0) { - /* high_cnt overflowed, so advance >32bit counter */ - _long_cnt++; - } -#else - /* advance >32bit counter */ - _long_cnt++; -#endif + xtimer_t *timer = timer_list_head; - /* swap overflow list to current timer list */ - timer_list_head = overflow_list_head; - overflow_list_head = NULL; + while (timer) { + assert(!timer->long_offset); + uint32_t elapsed = (uint32_t)*now - timer->start_time; + if (timer->offset < elapsed || timer->offset - elapsed < XTIMER_ISR_BACKOFF) { + assert(timer == timer_list_head); - _select_long_timers(); + /* make sure we don't fire too early */ + if (timer->offset > elapsed) { + while(_xtimer_now() - timer->start_time < timer->offset) {} + } + /* advance list */ + timer_list_head = timer->next; + /* make sure timer is recognized as being already fired */ + timer->offset = 0; + timer->start_time = 0; + timer->long_start_time = 0; + timer->next = NULL; + /* fire timer */ + _shoot(timer); + /* assign new head */ + timer = timer_list_head; + /* update current_time */ + *now = _xtimer_now(); + } + else { + timer->offset -= elapsed; + timer->start_time = (uint32_t)*now; + timer->long_start_time = (uint32_t)(*now >> 32); + timer = timer->next; + } + } } /** - * @brief main xtimer callback function + * @brief main xtimer callback function (called in an interrupt context) */ static void _timer_callback(void) { - uint32_t next_target; - uint32_t reference; - + uint64_t now; _in_handler = 1; + _lltimer_ongoing = false; + now = _xtimer_now64(); - DEBUG("_timer_callback() now=%" PRIu32 " (%" PRIu32 ")pleft=%" PRIu32 "\n", - xtimer_now().ticks32, _xtimer_lltimer_mask(xtimer_now().ticks32), - _xtimer_lltimer_mask(0xffffffff - xtimer_now().ticks32)); - - if (!timer_list_head) { - DEBUG("_timer_callback(): tick\n"); - /* there's no timer for this timer period, - * so this was a timer overflow callback. - * - * In this case, we advance to the next timer period. - */ - _next_period(); - - reference = 0; - - /* make sure the timer counter also arrived - * in the next timer period */ - while (_xtimer_lltimer_now() == _xtimer_lltimer_mask(0xFFFFFFFF)) {} - } - else { - /* we ended up in _timer_callback and there is - * a timer waiting. - */ - /* set our period reference to the current time. */ - reference = _xtimer_lltimer_now(); - } - -overflow: - /* check if next timers are close to expiring */ - while (timer_list_head && (_time_left(_xtimer_lltimer_mask(timer_list_head->target), reference) < XTIMER_ISR_BACKOFF)) { - /* make sure we don't fire too early */ - while (_time_left(_xtimer_lltimer_mask(timer_list_head->target), reference)) {} - - /* pick first timer in list */ - xtimer_t *timer = timer_list_head; - - /* advance list */ - timer_list_head = timer->next; - - /* make sure timer is recognized as being already fired */ - timer->target = 0; - timer->long_target = 0; - - /* fire timer */ - _shoot(timer); - } - - /* possibly executing all callbacks took enough - * time to overflow. In that case we advance to - * next timer period and check again for expired - * timers.*/ - /* check if the end of this period is very soon */ - uint32_t now = _xtimer_lltimer_now() + XTIMER_ISR_BACKOFF; - if (now < reference) { - DEBUG("_timer_callback: overflowed while executing callbacks. %i\n", - timer_list_head != NULL); - _next_period(); - /* wait till overflow */ - while( reference < _xtimer_lltimer_now()){} - reference = 0; - goto overflow; - } +update: + /* update short timer offset and fire */ + _update_short_timers(&now); + /* update long timer offset */ + _update_long_timers(&now); + /* update current time */ + now = _xtimer_now64(); if (timer_list_head) { - /* schedule callback on next timer target time */ - next_target = timer_list_head->target - XTIMER_OVERHEAD; - /* make sure we're not setting a time in the past */ - if (next_target < (_xtimer_now() + XTIMER_ISR_BACKOFF)) { - goto overflow; - } - } - else { - /* there's no timer planned for this timer period */ - /* schedule callback on next overflow */ - next_target = _xtimer_lltimer_mask(0xFFFFFFFF); - uint32_t now = _xtimer_lltimer_now(); - - /* check for overflow again */ - if (now < reference) { - _next_period(); - reference = 0; - goto overflow; + uint32_t elapsed = (uint32_t)now - timer_list_head->start_time; + if (timer_list_head->offset < elapsed || + timer_list_head->offset - elapsed < XTIMER_ISR_BACKOFF) { + goto update; } else { - /* check if the end of this period is very soon */ - if (_xtimer_lltimer_mask(now + XTIMER_ISR_BACKOFF) < now) { - /* spin until next period, then advance */ - while (_xtimer_lltimer_now() >= now) {} - _next_period(); - reference = 0; - goto overflow; - } + timer_list_head->offset -= elapsed; + timer_list_head->start_time = (uint32_t)now; + timer_list_head->long_start_time = (uint32_t)(now >> 32); } } - _in_handler = 0; /* set low level timer */ - _lltimer_set(next_target); + _schedule_earliest_lltimer((uint32_t)now); } From ca1ddeb9198b7ad5c392ade0d7e0f67ebdf07390 Mon Sep 17 00:00:00 2001 From: Hyungsin Date: Fri, 10 Jan 2020 10:07:56 -0800 Subject: [PATCH 02/11] tests/rng: reflecting xtimer's member change --- tests/rng/test.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/tests/rng/test.c b/tests/rng/test.c index c09414b52c4f..bd2989a59fac 100644 --- a/tests/rng/test.c +++ b/tests/rng/test.c @@ -412,8 +412,10 @@ void test_speed(uint32_t duration) /* collect samples as long as timer has not expired */ unsigned running = 1; xtimer_t xt = { - .target = 0, - .long_target = 0, + .start_time = 0, + .long_start_time = 0, + .offset = 0, + .long_offset = 0, .callback = cb_speed_timeout, .arg = &running, }; @@ -444,8 +446,10 @@ void test_speed_range(uint32_t duration, uint32_t low_thresh, uint32_t high_thre /* collect samples as long as timer has not expired */ unsigned running = 1; xtimer_t xt = { - .target = 0, - .long_target = 0, + .start_time = 0, + .long_start_time = 0, + .offset = 0, + .long_offset = 0, .callback = cb_speed_timeout, .arg = &running, }; From 35b6ed41f40773b09318efc5fe785dee792a81ce Mon Sep 17 00:00:00 2001 From: Hyungsin Date: Fri, 10 Jan 2020 10:08:42 -0800 Subject: [PATCH 03/11] tests/bench_timers: reflecting xtimer's member change --- tests/bench_timers/main.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/tests/bench_timers/main.c b/tests/bench_timers/main.c index bc250b34b841..4acdb0b9ec21 100644 --- a/tests/bench_timers/main.c +++ b/tests/bench_timers/main.c @@ -374,14 +374,18 @@ static void run_test(test_ctx_t *ctx, uint32_t interval, unsigned int variant) interval += TEST_MIN; unsigned int interval_ref = TIM_TEST_TO_REF(interval); xtimer_t xt = { - .target = 0, - .long_target = 0, + .start_time = 0, + .long_start_time = 0, + .offset = 0, + .long_offset = 0, .callback = cb, .arg = ctx, }; xtimer_t xt_parallel = { - .target = 0, - .long_target = 0, + .start_time = 0, + .long_start_time = 0, + .offset = 0, + .long_offset = 0, .callback = nop, .arg = NULL, }; From a18f9318c713f17012bed45044fd6d67249f2a35 Mon Sep 17 00:00:00 2001 From: Hyungsin Date: Fri, 10 Jan 2020 10:11:08 -0800 Subject: [PATCH 04/11] sys/shell/commands: reflecting xtimer's member change --- sys/shell/commands/sc_gnrc_rpl.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sys/shell/commands/sc_gnrc_rpl.c b/sys/shell/commands/sc_gnrc_rpl.c index 284a6745d838..7fb707f7e509 100644 --- a/sys/shell/commands/sc_gnrc_rpl.c +++ b/sys/shell/commands/sc_gnrc_rpl.c @@ -292,8 +292,10 @@ int _gnrc_rpl_dodag_show(void) gnrc_rpl_instances[i].mop, gnrc_rpl_instances[i].of->ocp, gnrc_rpl_instances[i].min_hop_rank_inc, gnrc_rpl_instances[i].max_rank_inc); - tc = (((uint64_t) dodag->trickle.msg_timer.long_target << 32) - | dodag->trickle.msg_timer.target) - xnow; + tc = _xtimer_usec_from_ticks64(((uint64_t) dodag->trickle.msg_timer.long_offset << 32) + | dodag->trickle.msg_timer.offset) + - (xnow - _xtimer_usec_from_ticks64( + (uint64_t)dodag->trickle.msg_timer.long_start_time << 32 | dodag->trickle.msg_timer.start_time)); tc = (int64_t) tc < 0 ? 0 : tc / US_PER_SEC; printf("\tdodag [%s | R: %d | OP: %s | PIO: %s | " From 6f5154b98e707f472e3fa92145625f4d0ca75147 Mon Sep 17 00:00:00 2001 From: Hyungsin Date: Fri, 10 Jan 2020 10:12:55 -0800 Subject: [PATCH 05/11] sys/evtimer: reflecting xtimer's member change --- sys/evtimer/evtimer.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sys/evtimer/evtimer.c b/sys/evtimer/evtimer.c index 52df48ff263a..aabff9fafc63 100644 --- a/sys/evtimer/evtimer.c +++ b/sys/evtimer/evtimer.c @@ -115,8 +115,10 @@ static void _update_timer(evtimer_t *evtimer) static uint32_t _get_offset(xtimer_t *timer) { uint64_t now_us = xtimer_now_usec64(); - uint64_t target_us = _xtimer_usec_from_ticks64( - ((uint64_t)timer->long_target) << 32 | timer->target); + uint64_t start_us = _xtimer_usec_from_ticks64( + ((uint64_t)timer->long_start_time << 32) | timer->start_time); + uint64_t target_us = start_us + _xtimer_usec_from_ticks64( + ((uint64_t)timer->long_offset) << 32 | timer->offset); if (target_us <= now_us) { return 0; From 3289acccfb20b6e12c8eb1e6fc0a4b7596912f48 Mon Sep 17 00:00:00 2001 From: Hyungsin Date: Fri, 10 Jan 2020 10:13:52 -0800 Subject: [PATCH 06/11] pkg/semtech-loramac/contrib: reflecting xtimer's member change --- pkg/semtech-loramac/contrib/semtech_loramac_timer.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pkg/semtech-loramac/contrib/semtech_loramac_timer.c b/pkg/semtech-loramac/contrib/semtech_loramac_timer.c index 346bc7fe935d..1725262f2d9a 100644 --- a/pkg/semtech-loramac/contrib/semtech_loramac_timer.c +++ b/pkg/semtech-loramac/contrib/semtech_loramac_timer.c @@ -27,7 +27,10 @@ extern kernel_pid_t semtech_loramac_pid; void TimerInit(TimerEvent_t *obj, void (*cb)(void)) { - obj->dev.target = 0; + obj->dev.start_time = 0; + obj->dev.long_start_time = 0; + obj->dev.offset = 0; + obj->dev.long_offset = 0; obj->running = 0; obj->cb = cb; } From 8661205c6d655394a1dc3e95df8627f53ee4f6a5 Mon Sep 17 00:00:00 2001 From: Hyungsin Date: Fri, 10 Jan 2020 10:14:37 -0800 Subject: [PATCH 07/11] cpu/esp32: reflecting xtimer's member change --- cpu/esp32/esp_xtimer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpu/esp32/esp_xtimer.c b/cpu/esp32/esp_xtimer.c index 9060ff9ece54..4af9a2560afa 100644 --- a/cpu/esp32/esp_xtimer.c +++ b/cpu/esp32/esp_xtimer.c @@ -148,7 +148,7 @@ void ets_timer_arm_us(ETSTimer *timer, uint32_t tmout, bool repeat) xtimer_set(&e2xt->xtimer, tmout); - e2xt->ets_timer->timer_expire = e2xt->xtimer.target; + e2xt->ets_timer->timer_expire = e2xt->xtimer.start_time + e2xt->xtimer.offset; e2xt->ets_timer->timer_period = repeat ? tmout : 0; } From 1ee8801306b900b3cad91c7abe0979e73cb464be Mon Sep 17 00:00:00 2001 From: Hyungsin Date: Fri, 10 Jan 2020 10:16:04 -0800 Subject: [PATCH 08/11] pkg/ndn-riot: add a patch to reflect xtimer's member change --- .../0001-update-xtimer_member_names.patch | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 pkg/ndn-riot/patches/0001-update-xtimer_member_names.patch diff --git a/pkg/ndn-riot/patches/0001-update-xtimer_member_names.patch b/pkg/ndn-riot/patches/0001-update-xtimer_member_names.patch new file mode 100644 index 000000000000..40b3fa1da1a6 --- /dev/null +++ b/pkg/ndn-riot/patches/0001-update-xtimer_member_names.patch @@ -0,0 +1,52 @@ +From 22f5984e32bec116e3449ebad1b29b2a18f4d93e Mon Sep 17 00:00:00 2001 +From: Michel Rottleuthner +Date: Thu, 9 Jan 2020 11:16:38 +0100 +Subject: [PATCH] update xtimer_t member names + +--- + app.c | 2 +- + l2.c | 2 +- + pit.c | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/app.c b/app.c +index 8d37bd9..da9fc3c 100644 +--- a/app.c ++++ b/app.c +@@ -380,7 +380,7 @@ int ndn_app_schedule(ndn_app_t* handle, ndn_app_sched_cb_t cb, void* context, + if (entry == NULL) return -1; + + // initialize the timer +- entry->timer.target = entry->timer.long_target = 0; ++ entry->timer.offset = entry->timer.long_offset = 0; + + // initialize the msg struct + entry->timer_msg.type = MSG_XTIMER; +diff --git a/l2.c b/l2.c +index 77d6be4..b64b9df 100644 +--- a/l2.c ++++ b/l2.c +@@ -155,7 +155,7 @@ ndn_shared_block_t* ndn_l2_frag_receive(kernel_pid_t iface, + entry->id = id; + + // initialize timer +- entry->timer.target = entry->timer.long_target = 0; ++ entry->timer.offset = entry->timer.long_offset = 0; + entry->timer_msg.type = NDN_L2_FRAG_MSG_TYPE_TIMEOUT; + entry->timer_msg.content.ptr = (char*)(&entry->timer_msg); + +diff --git a/pit.c b/pit.c +index 644cf08..944a07c 100644 +--- a/pit.c ++++ b/pit.c +@@ -155,7 +155,7 @@ int ndn_pit_add(kernel_pid_t face_id, int face_type, ndn_shared_block_t* si, + *pit_entry = entry; + + /* initialize the timer */ +- entry->timer.target = entry->timer.long_target = 0; ++ entry->timer.offset = entry->timer.long_offset = 0; + + /* initialize the msg struct */ + entry->timer_msg.type = NDN_PIT_MSG_TYPE_TIMEOUT; +-- +2.24.1 From 3e4a86d84bfc44097daa13f2da38c53c2b8f0d5e Mon Sep 17 00:00:00 2001 From: Hyungsin Date: Fri, 10 Jan 2020 10:17:01 -0800 Subject: [PATCH 09/11] pkg/nimble: add a patch to reflect xtimer's member change --- .../patches/0001-xtimer_member_names.patch | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 pkg/nimble/patches/0001-xtimer_member_names.patch diff --git a/pkg/nimble/patches/0001-xtimer_member_names.patch b/pkg/nimble/patches/0001-xtimer_member_names.patch new file mode 100644 index 000000000000..9152a393d4f3 --- /dev/null +++ b/pkg/nimble/patches/0001-xtimer_member_names.patch @@ -0,0 +1,24 @@ +From 6b1223df6884bcfd00f4ecc8918b790baf041021 Mon Sep 17 00:00:00 2001 +From: Michel Rottleuthner +Date: Wed, 8 Jan 2020 19:50:48 +0100 +Subject: [PATCH] update xtimer_t member names + +--- + porting/npl/riot/include/nimble/nimble_npl_os.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/porting/npl/riot/include/nimble/nimble_npl_os.h b/porting/npl/riot/include/nimble/nimble_npl_os.h +index 67eb74e1..61c1ea8a 100644 +--- a/porting/npl/riot/include/nimble/nimble_npl_os.h ++++ b/porting/npl/riot/include/nimble/nimble_npl_os.h +@@ -209,7 +209,7 @@ ble_npl_callout_stop(struct ble_npl_callout *co) + static inline bool + ble_npl_callout_is_active(struct ble_npl_callout *c) + { +- return (c->timer.target || c->timer.long_target); ++ return (c->timer.offset || c->timer.long_offset); + } + + static inline ble_npl_time_t +-- +2.24.1 From 6eed5b9d43ba51c7e2e39b9c1d206f6b212fffb3 Mon Sep 17 00:00:00 2001 From: Hyungsin Date: Fri, 10 Jan 2020 11:02:51 -0800 Subject: [PATCH 10/11] remove XTIMER_OVERHEAD --- boards/common/esp8266/include/board_common.h | 2 -- boards/common/iotlab/include/board_common.h | 1 - boards/common/nucleo/include/board_nucleo.h | 6 ------ boards/frdm-kw41z/include/board.h | 1 - boards/hamilton/include/board.h | 1 - boards/msba2/include/board.h | 7 ------- boards/mulle/include/board.h | 2 -- boards/phynode-kw41z/include/board.h | 1 - boards/stm32f4discovery/include/board.h | 1 - boards/teensy31/include/board.h | 1 - boards/usb-kw41z/include/board.h | 1 - cpu/native/include/periph_conf.h | 2 -- drivers/dose/dose.c | 2 +- 13 files changed, 1 insertion(+), 27 deletions(-) diff --git a/boards/common/esp8266/include/board_common.h b/boards/common/esp8266/include/board_common.h index 90942b864d78..1392fcea24cf 100644 --- a/boards/common/esp8266/include/board_common.h +++ b/boards/common/esp8266/include/board_common.h @@ -73,8 +73,6 @@ extern "C" { * @name XTimer configuration * @{ */ -#define XTIMER_OVERHEAD (0U) - #if defined(MODULE_ESP_SW_TIMER) #define XTIMER_BACKOFF (100U) #define XTIMER_ISR_BACKOFF (100U) diff --git a/boards/common/iotlab/include/board_common.h b/boards/common/iotlab/include/board_common.h index a7d67c0e1e52..bf3f620bb9ca 100644 --- a/boards/common/iotlab/include/board_common.h +++ b/boards/common/iotlab/include/board_common.h @@ -50,7 +50,6 @@ extern "C" { * @{ */ #define XTIMER_WIDTH (16U) -#define XTIMER_OVERHEAD (6U) /** @} */ /** diff --git a/boards/common/nucleo/include/board_nucleo.h b/boards/common/nucleo/include/board_nucleo.h index 47ae5a8f1079..ae4cf119e2e2 100644 --- a/boards/common/nucleo/include/board_nucleo.h +++ b/boards/common/nucleo/include/board_nucleo.h @@ -37,10 +37,6 @@ extern "C" { #define XTIMER_WIDTH (16) #endif -#if defined(CPU_MODEL_STM32F334R8) -#define XTIMER_OVERHEAD (5) -#endif - #if defined(CPU_FAM_STM32F1) #define XTIMER_WIDTH (16) #define XTIMER_BACKOFF (19) @@ -48,12 +44,10 @@ extern "C" { #if defined(CPU_FAM_STM32L1) #define XTIMER_BACKOFF (11) -#define XTIMER_OVERHEAD (6) #endif #if defined(CPU_FAM_STM32F4) || defined(CPU_MODEL_STM32F303ZE) #define XTIMER_BACKOFF (8) -#define XTIMER_OVERHEAD (6) #endif /** @} */ diff --git a/boards/frdm-kw41z/include/board.h b/boards/frdm-kw41z/include/board.h index f80508cd4952..b905078f885e 100644 --- a/boards/frdm-kw41z/include/board.h +++ b/boards/frdm-kw41z/include/board.h @@ -85,7 +85,6 @@ extern "C" #define XTIMER_WIDTH (16) #define XTIMER_BACKOFF (5) #define XTIMER_ISR_BACKOFF (5) -#define XTIMER_OVERHEAD (4) #define XTIMER_HZ (32768ul) #endif /** @} */ diff --git a/boards/hamilton/include/board.h b/boards/hamilton/include/board.h index 5bc11e93c096..5fe82d16a110 100644 --- a/boards/hamilton/include/board.h +++ b/boards/hamilton/include/board.h @@ -36,7 +36,6 @@ extern "C" { */ #define XTIMER_DEV TIMER_DEV(1) #define XTIMER_CHAN (0) -#define XTIMER_OVERHEAD (0) /** @} */ /** diff --git a/boards/msba2/include/board.h b/boards/msba2/include/board.h index ec14288a9220..ec04a03fd72c 100644 --- a/boards/msba2/include/board.h +++ b/boards/msba2/include/board.h @@ -45,13 +45,6 @@ extern "C" { #define LED1_TOGGLE (FIO3PIN ^= LED1_MASK) /** @} */ -/** - * @name xtimer tuning values - * @{ - */ -#define XTIMER_OVERHEAD 7 -/** @} */ - #ifdef __cplusplus } #endif diff --git a/boards/mulle/include/board.h b/boards/mulle/include/board.h index ba396f9e5bf2..59271dd58013 100644 --- a/boards/mulle/include/board.h +++ b/boards/mulle/include/board.h @@ -49,7 +49,6 @@ #define XTIMER_WIDTH (16) #define XTIMER_BACKOFF (4) #define XTIMER_ISR_BACKOFF (4) -#define XTIMER_OVERHEAD (3) #define XTIMER_HZ (32768ul) #else /* PIT xtimer configuration */ @@ -57,7 +56,6 @@ #define XTIMER_CHAN (0) #define XTIMER_BACKOFF (40) #define XTIMER_ISR_BACKOFF (40) -#define XTIMER_OVERHEAD (30) #endif /** @} */ diff --git a/boards/phynode-kw41z/include/board.h b/boards/phynode-kw41z/include/board.h index dba1849176ea..80beb71fc642 100644 --- a/boards/phynode-kw41z/include/board.h +++ b/boards/phynode-kw41z/include/board.h @@ -100,7 +100,6 @@ extern "C" #define XTIMER_WIDTH (16) #define XTIMER_BACKOFF (5) #define XTIMER_ISR_BACKOFF (5) -#define XTIMER_OVERHEAD (4) #define XTIMER_HZ (32768ul) #endif /** @} */ diff --git a/boards/stm32f4discovery/include/board.h b/boards/stm32f4discovery/include/board.h index ae9c0e650c59..fc0c4af577ac 100644 --- a/boards/stm32f4discovery/include/board.h +++ b/boards/stm32f4discovery/include/board.h @@ -31,7 +31,6 @@ extern "C" { * @name xtimer configuration * @{ */ -#define XTIMER_OVERHEAD (6) #define XTIMER_BACKOFF (10) /** @} */ diff --git a/boards/teensy31/include/board.h b/boards/teensy31/include/board.h index 31da950e29e2..7704242794e5 100644 --- a/boards/teensy31/include/board.h +++ b/boards/teensy31/include/board.h @@ -43,7 +43,6 @@ extern "C" { #define XTIMER_CHAN (0) #define XTIMER_BACKOFF (40) #define XTIMER_ISR_BACKOFF (40) -#define XTIMER_OVERHEAD (30) /** @} */ /** diff --git a/boards/usb-kw41z/include/board.h b/boards/usb-kw41z/include/board.h index 7634b3806fa1..d3e2170f2f8b 100644 --- a/boards/usb-kw41z/include/board.h +++ b/boards/usb-kw41z/include/board.h @@ -96,7 +96,6 @@ extern "C" #define XTIMER_WIDTH (16) #define XTIMER_BACKOFF (5) #define XTIMER_ISR_BACKOFF (5) -#define XTIMER_OVERHEAD (4) #define XTIMER_HZ (32768ul) #endif /** @} */ diff --git a/cpu/native/include/periph_conf.h b/cpu/native/include/periph_conf.h index 90de7a52339f..68075ac85f54 100644 --- a/cpu/native/include/periph_conf.h +++ b/cpu/native/include/periph_conf.h @@ -44,8 +44,6 @@ extern "C" { /** * @brief xtimer configuration */ -#define XTIMER_OVERHEAD 14 - /* timer_set_absolute() has a high margin for possible underflow if set with * value not far in the future. To prevent this, we set high backoff values * here. diff --git a/drivers/dose/dose.c b/drivers/dose/dose.c index a7d220d933ca..4b835e3aad73 100644 --- a/drivers/dose/dose.c +++ b/drivers/dose/dose.c @@ -534,7 +534,7 @@ static const netdev_driver_t netdev_driver_dose = { void dose_setup(dose_t *ctx, const dose_params_t *params) { - static const xtimer_ticks32_t min_timeout = {.ticks32 = XTIMER_BACKOFF + XTIMER_OVERHEAD}; + static const xtimer_ticks32_t min_timeout = {.ticks32 = XTIMER_BACKOFF}; ctx->netdev.driver = &netdev_driver_dose; From 992afd9017cc671e12383121ecb9c9aac7e212a3 Mon Sep 17 00:00:00 2001 From: Hyungsin Date: Sat, 11 Jan 2020 03:55:27 -0800 Subject: [PATCH 11/11] tests/pkg_semtech-loramac: add more unsupported boards --- tests/pkg_semtech-loramac/Makefile | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/pkg_semtech-loramac/Makefile b/tests/pkg_semtech-loramac/Makefile index 35151678c9a8..46161d1dc4be 100644 --- a/tests/pkg_semtech-loramac/Makefile +++ b/tests/pkg_semtech-loramac/Makefile @@ -2,9 +2,11 @@ BOARD ?= b-l072z-lrwan1 include ../Makefile.tests_common -# waspmote-pro and arduino-meag2560 don't have enough RAM to support another -# thread dedicated to RX messages -BOARD_WITHOUT_LORAMAC_RX := arduino-mega2560 waspmote-pro +BOARD_WITHOUT_LORAMAC_RX := \ + arduino-mega2560 \ + i-nuncleo-lrwan1 \ + stm32f0discovery \ + waspmote-pro \ LORA_DRIVER ?= sx1276 LORA_REGION ?= EU868