From 085383bfaeda67302a4359d3aecdb4555c5fb46f Mon Sep 17 00:00:00 2001 From: Kaspar Schleiser Date: Wed, 29 Jul 2015 19:59:16 +0200 Subject: [PATCH] core: remove hwtimer, switch schedstatistics to xtimer --- Makefile.dep | 4 + Makefile.pseudomodules | 1 + core/hwtimer.c | 213 ------------------------------- core/include/arch/hwtimer_arch.h | 85 ------------ core/include/hwtimer.h | 196 ---------------------------- core/include/sched.h | 2 +- core/kernel_init.c | 12 +- core/sched.c | 16 +-- core/thread.c | 1 - 9 files changed, 23 insertions(+), 507 deletions(-) delete mode 100644 core/hwtimer.c delete mode 100644 core/include/arch/hwtimer_arch.h delete mode 100644 core/include/hwtimer.h diff --git a/Makefile.dep b/Makefile.dep index a9d163547b..94c2441f7e 100644 --- a/Makefile.dep +++ b/Makefile.dep @@ -2,6 +2,10 @@ ifneq (,$(filter gnrc_%,$(filter-out gnrc_netapi gnrc_netreg gnrc_netif% gnrc_pk USEMODULE += gnrc endif +ifneq (,$(filter schedstatistics,$(USEMODULE))) + USEMODULE += xtimer +endif + ifneq (,$(filter gnrc_netif_default,$(USEMODULE))) USEMODULE += gnrc_netif endif diff --git a/Makefile.pseudomodules b/Makefile.pseudomodules index 1e123a2977..47b47a6699 100644 --- a/Makefile.pseudomodules +++ b/Makefile.pseudomodules @@ -13,6 +13,7 @@ PSEUDOMODULES += log PSEUDOMODULES += log_printfnoformat PSEUDOMODULES += newlib PSEUDOMODULES += pktqueue +PSEUDOMODULES += schedstatistics # include variants of the AT86RF2xx drivers as pseudo modules PSEUDOMODULES += at86rf23% diff --git a/core/hwtimer.c b/core/hwtimer.c deleted file mode 100644 index b1bba3a2be..0000000000 --- a/core/hwtimer.c +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Copyright (C) 2014 Freie Universität Berlin - * - * 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 core_hwtimer - * @{ - * - * @file - * @brief Hardware timer abstraction implementation - * - * @author Heiko Will - * @author Thomas Hillebrandt - * @author Kaspar Schleiser - * @author Oliver Hahm - * @author Kévin Roussel - * - * @} - */ - -#include - -#include "kernel.h" -#include "thread.h" -#include "lifo.h" -#include "mutex.h" -#include "irq.h" -#include "board.h" - -#define ENABLE_DEBUG (0) -#include "debug.h" - -#include "log.h" - -#include "hwtimer.h" -#include "hwtimer_cpu.h" -#include "arch/hwtimer_arch.h" - -/*---------------------------------------------------------------------------*/ - -typedef struct hwtimer_t { - void (*callback)(void*); - void *data; -} hwtimer_t; - -static hwtimer_t timer[HWTIMER_MAXTIMERS]; -static int lifo[HWTIMER_MAXTIMERS + 1]; - -/*---------------------------------------------------------------------------*/ - -static void multiplexer(int source) -{ - lifo_insert(lifo, source); - lpm_prevent_sleep--; - - timer[source].callback(timer[source].data); -} - -static void hwtimer_releasemutex(void* mutex) { - mutex_unlock((mutex_t*) mutex); -} - -void hwtimer_spin(unsigned long ticks) -{ - DEBUG("hwtimer_spin ticks=%lu\n", ticks); - - unsigned long start = hwtimer_arch_now(); - /* compute destination time, possibly resulting in an overflow */ - unsigned long stop = ((start + ticks) & HWTIMER_MAXTICKS); - - /* - * If there is an overflow (that is: stop time is inferior to start), - * hwtimer_arch_now needs to spin until it has overflowed as well. - */ - if (stop < start) { - while (hwtimer_arch_now() > start) /* do nothing */; - } - - /* wait until we have passed destination (stop) time */ - while (hwtimer_arch_now() < stop) /* do nothing again */; -} - -/*---------------------------------------------------------------------------*/ - -void hwtimer_init(void) -{ - hwtimer_init_comp(F_CPU); -} - -/*---------------------------------------------------------------------------*/ - -void hwtimer_init_comp(uint32_t fcpu) -{ - hwtimer_arch_init(multiplexer, fcpu); - - lifo_init(lifo, HWTIMER_MAXTIMERS); - - for (int i = 0; i < HWTIMER_MAXTIMERS; i++) { - lifo_insert(lifo, i); - } -} - -/*---------------------------------------------------------------------------*/ - -int hwtimer_active(void) -{ - return (!lifo_empty(lifo)); -} - -/*---------------------------------------------------------------------------*/ - -unsigned long hwtimer_now(void) -{ - return hwtimer_arch_now(); -} - -/*---------------------------------------------------------------------------*/ - -void hwtimer_wait(unsigned long ticks) -{ - DEBUG("hwtimer_wait ticks=%lu\n", ticks); - - if ((ticks <= (HWTIMER_SPIN_BARRIER)) || inISR()) { - hwtimer_spin(ticks); - return; - } - - mutex_t mutex = MUTEX_INIT; - mutex_lock(&mutex); - int res = hwtimer_set(ticks - (HWTIMER_WAIT_OVERHEAD), hwtimer_releasemutex, &mutex); - if (res == -1) { - mutex_unlock(&mutex); - hwtimer_spin(ticks); - return; - } - - /* try to lock mutex again will cause the thread to go into - * STATUS_MUTEX_BLOCKED until hwtimer fires the releasemutex */ - mutex_lock(&mutex); -} - -/*---------------------------------------------------------------------------*/ - - -static int _hwtimer_set(unsigned long offset, void (*callback)(void*), void *ptr, bool absolute) -{ - DEBUG("_hwtimer_set: offset=%lu callback=%p ptr=%p absolute=%d\n", offset, callback, ptr, absolute); - - unsigned state; - - state = disableIRQ(); - - int n = lifo_get(lifo); - - if (n == -1) { - restoreIRQ(state); - - LOG_WARNING("No hwtimer left.\n"); - return -1; - } - - timer[n].callback = callback; - timer[n].data = ptr; - - if (absolute) { - DEBUG("hwtimer_arch_set_absolute n=%d\n", n); - hwtimer_arch_set_absolute(offset, n); - } - else { - DEBUG("hwtimer_arch_set n=%d\n", n); - hwtimer_arch_set(offset, n); - } - - lpm_prevent_sleep++; - - restoreIRQ(state); - - return n; -} - -int hwtimer_set(unsigned long offset, void (*callback)(void*), void *ptr) -{ - return _hwtimer_set(offset, callback, ptr, false); -} - -int hwtimer_set_absolute(unsigned long offset, void (*callback)(void*), void *ptr) -{ - return _hwtimer_set(offset, callback, ptr, true); -} - - -/*---------------------------------------------------------------------------*/ - -int hwtimer_remove(int n) -{ - DEBUG("hwtimer_remove n=%d\n", n); - - unsigned state = disableIRQ(); - hwtimer_arch_unset(n); - - lifo_insert(lifo, n); - timer[n].callback = NULL; - - lpm_prevent_sleep--; - - restoreIRQ(state); - - return 1; -} diff --git a/core/include/arch/hwtimer_arch.h b/core/include/arch/hwtimer_arch.h deleted file mode 100644 index 9a807235b4..0000000000 --- a/core/include/arch/hwtimer_arch.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2014 Freie Universität Berlin - * - * 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 core_arch - * @{ - * - * @file - * @brief The kernel's hardware timer abstraction interface - * - * @author Thomas Hillebrandt - * @author Heiko Will - * @author Kaspar Schleiser - * @author Hauke Petersen - */ - -#ifndef HWTIMER_ARCH_H_ -#define HWTIMER_ARCH_H_ - -#ifdef __cplusplus - extern "C" { -#endif - -#include - -/** - * @brief Initialize architecture dependent kernel timer support - * - * @param[in] handler callback that is called when timer @p offset is reached - * @param[in] fcpu the core CPU-frequency for tick interval calculation - */ -void hwtimer_arch_init(void (*handler)(int), uint32_t fcpu); - -/** - * @brief Enable interrupts of hardware timers - */ -void hwtimer_arch_enable_interrupt(void); - -/** - * @brief Disable interrupts of hardware timers - */ -void hwtimer_arch_disable_interrupt(void); - -/** - * @brief Set a kernel timer to raise an interrupt after @p offset kernel timer - * ticks from now - * - * @param[in] offset number of ticks until the timer fires - * @param[in] timer the channel to set - */ -void hwtimer_arch_set(unsigned long offset, short timer); - -/** - * @brief Set a kernel timer to raise an interrupt at specified system time. - * - * @param[in] value absolute timer tick value to set a timer channel to - * @param[in] timer the channel to set - */ -void hwtimer_arch_set_absolute(unsigned long value, short timer); - -/** - * @brief Unset the kernel timer with the given timer ID - * - * @param[in] timer the channel to unset - */ -void hwtimer_arch_unset(short timer); - -/** - * @brief Get the current tick count of the default hardware timer - * - * @return the current value of the hwtimer - */ -unsigned long hwtimer_arch_now(void); - -#ifdef __cplusplus -} -#endif - -#endif /* HWTIMER_ARCH_H_ */ -/** @} */ diff --git a/core/include/hwtimer.h b/core/include/hwtimer.h deleted file mode 100644 index a32b39b164..0000000000 --- a/core/include/hwtimer.h +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright (C) 2013 Freie Universität Berlin - * - * 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. - */ - -/** - * @defgroup core_hwtimer Hardware timer - * @ingroup core - * @brief Hardware timer interface - * - * The Hardware timers are directly mapped to hardware timers with minimum - * latency. They are intended for short intervals and to be used in time - * critical low-level drivers (e.g. radio). hwtimer callbacks are run in the - * interrupt context and must use the shortest possible execution time (e.g. - * set a flag and trigger a worker thread). - * - * The hardware timer should not be used (until you know what - * you're doing), use \ref sys_vtimer instead. - * - * @{ - * - * @file - * @brief HW-timer abstraction - * - * @author Heiko Will - * @author Kaspar Schleiser - * @author Michael Baar - */ - -#ifndef HWTIMER_H -#define HWTIMER_H - -#include -#include "hwtimer_cpu.h" -#include "board.h" - -#ifdef __cplusplus - extern "C" { -#endif - -/** - * @brief Number of kernel timer ticks per second - * @def HWTIMER_SPEED - */ -#ifndef HWTIMER_SPEED -#warning "HWTIMER_SPEED undefined. Set HWTIMER_SPEED to the number of ticks \ -per second for the current architecture." -#endif - -/** - * @brief Upper bound for hwtimer_spin - * - * @note Barrier starting from which hwtimer_spin is called instead - * of setting a timer and yielding the thread. - * - * Boards should override this. - * - * @def HWTIMER_SPIN_BARRIER - */ -#ifndef HWTIMER_SPIN_BARRIER -#define HWTIMER_SPIN_BARRIER (6) -#endif - -/** - * @brief Overhead of the `hwtimer_wait` function - * - * @note This value is used to decrease the number of ticks that - * `hwtimer_wait` uses to set the actual hardware timer. - * - * The goal is to make sure the number of ticks spent in the - * function corresponds to the ticks argument it was given. - * - * Boards should override this. - * - * @def HWTIMER_WAIT_OVERHEAD - */ -#ifndef HWTIMER_WAIT_OVERHEAD -#define HWTIMER_WAIT_OVERHEAD (2) -#endif - -/** - * @brief Convert microseconds to kernel timer ticks - * @param[in] us number of microseconds - * @return kernel timer ticks - */ -#if HWTIMER_SPEED > 1000000L -#define HWTIMER_TICKS(us) ((us) * (HWTIMER_SPEED / 1000000L)) -#else -#define HWTIMER_TICKS(us) ((us) / (1000000L / HWTIMER_SPEED)) -#endif - -/** - * @brief Convert ticks to microseconds - * @param[in] ticks number of ticks - * @return microseconds - */ -#if HWTIMER_SPEED > 1000000L -#define HWTIMER_TICKS_TO_US(ticks) ((ticks) / (HWTIMER_SPEED / 1000000L)) -#else -#define HWTIMER_TICKS_TO_US(ticks) ((ticks) * (1000000L / HWTIMER_SPEED)) -#endif - -/** - * @brief Maximum hwtimer tick count (before overflow) - * @def HWTIMER_MAXTICKS - */ -#ifndef HWTIMER_MAXTICKS -#warning "HWTIMER_MAXTICKS undefined. Set HWTIMER_MAXTICKS to the maximum \ -number of ticks countable on the current architecture." -#endif - -/** - * @brief microseconds before hwtimer overflow - */ -#if HWTIMER_SPEED > 1000000L -#define HWTIMER_OVERFLOW_MICROS() (HWTIMER_MAXTICKS / HWTIMER_SPEED * 1000000L) -#else -#define HWTIMER_OVERFLOW_MICROS() (1000000L / HWTIMER_SPEED * HWTIMER_MAXTICKS) -#endif - -typedef uint32_t timer_tick_t; /**< data type for hwtimer ticks */ - -/** - * @brief initialize the hwtimer module - */ -void hwtimer_init(void); - -/** - * @brief Get the hardware time - * @return The current tick count of the hardware timer - */ -unsigned long hwtimer_now(void); - -/** - * @brief Set a kernel timer - * @param[in] offset Offset until callback invocation in timer ticks - * @param[in] callback Callback function - * @param[in] ptr Argument to callback function - * @return timer id - */ -int hwtimer_set(unsigned long offset, void (*callback)(void*), void *ptr); - -/** - * @brief Set a kernel timer - * @param[in] absolute Absolute timer counter value for invocation - * of handler - * @param[in] callback Callback function - * @param[in] ptr Argument to callback function - * @return timer id - */ -int hwtimer_set_absolute(unsigned long absolute, - void (*callback)(void*), void *ptr); - -/** - * @brief Remove a kernel timer - * @param[in] t Id of timer to remove - * @return 1 on success - */ -int hwtimer_remove(int t); - -/** - * @brief Delay current thread - * @param[in] ticks Number of kernel ticks to delay - */ -void hwtimer_wait(unsigned long ticks); - -/** - * @brief determine if the hwtimer module is initialized - * @return 1 if the hwtimer module is initialized - */ -int hwtimer_active(void); - -/** - * @brief initialize hwtimer module data structures and hardware - * - * @param[in] fcpu cpu frequency - */ -void hwtimer_init_comp(uint32_t fcpu); - -/** - * @brief Delay current thread, spinning. Use only in interrupts for - * VERY short delays! - * - * @param[in] ticks Number of kernel ticks to delay - */ -void hwtimer_spin(unsigned long ticks); - -#ifdef __cplusplus -} -#endif - -/** @} */ -#endif /* HWTIMER_H */ diff --git a/core/include/sched.h b/core/include/sched.h index 31ed0bb3b4..7f0436377a 100644 --- a/core/include/sched.h +++ b/core/include/sched.h @@ -164,7 +164,7 @@ extern volatile kernel_pid_t sched_active_pid; */ extern clist_node_t *sched_runqueues[SCHED_PRIO_LEVELS]; -#if SCHEDSTATISTICS +#ifdef MODULE_SCHEDSTATISTICS /** * Scheduler statistics */ diff --git a/core/kernel_init.c b/core/kernel_init.c index 311c7a290a..b89e1ad22d 100644 --- a/core/kernel_init.c +++ b/core/kernel_init.c @@ -29,10 +29,13 @@ #include "cpu.h" #include "lpm.h" #include "thread.h" -#include "hwtimer.h" #include "irq.h" #include "log.h" +#ifdef MODULE_SCHEDSTATISTICS +#include "sched.h" +#endif + #define ENABLE_DEBUG (0) #include "debug.h" @@ -51,6 +54,11 @@ static void *main_trampoline(void *arg) auto_init(); #endif +#ifdef MODULE_SCHEDSTATISTICS + schedstat *stat = &sched_pidlist[thread_getpid()]; + stat->laststart = 0; +#endif + LOG_INFO("main(): This is RIOT! (Version: " RIOT_VERSION ")\n"); main(); @@ -85,8 +93,6 @@ void kernel_init(void) { (void) disableIRQ(); - hwtimer_init(); - thread_create(idle_stack, sizeof(idle_stack), THREAD_PRIORITY_IDLE, CREATE_WOUT_YIELD | CREATE_STACKTEST, diff --git a/core/sched.c b/core/sched.c index a06c9cf41f..2429496bdc 100644 --- a/core/sched.c +++ b/core/sched.c @@ -31,8 +31,8 @@ #include "irq.h" #include "log.h" -#if SCHEDSTATISTICS -#include "hwtimer.h" +#ifdef MODULE_SCHEDSTATISTICS +#include "xtimer.h" #endif #define ENABLE_DEBUG (0) @@ -55,7 +55,7 @@ volatile kernel_pid_t sched_active_pid = KERNEL_PID_UNDEF; clist_node_t *sched_runqueues[SCHED_PRIO_LEVELS]; static uint32_t runqueue_bitcache = 0; -#if SCHEDSTATISTICS +#ifdef MODULE_SCHEDSTATISTICS static void (*sched_cb) (uint32_t timestamp, uint32_t value) = NULL; schedstat sched_pidlist[KERNEL_PID_LAST + 1]; #endif @@ -81,8 +81,8 @@ int sched_run(void) return 0; } -#ifdef SCHEDSTATISTICS - unsigned long time = hwtimer_now(); +#ifdef MODULE_SCHEDSTATISTICS + unsigned long time = xtimer_now(); #endif if (active_thread) { @@ -96,7 +96,7 @@ int sched_run(void) } #endif -#ifdef SCHEDSTATISTICS +#ifdef MODULE_SCHEDSTATISTICS schedstat *active_stat = &sched_pidlist[active_thread->pid]; if (active_stat->laststart) { active_stat->runtime_ticks += time - active_stat->laststart; @@ -104,7 +104,7 @@ int sched_run(void) #endif } -#if SCHEDSTATISTICS +#ifdef MODULE_SCHEDSTATISTICS schedstat *next_stat = &sched_pidlist[next_thread->pid]; next_stat->laststart = time; next_stat->schedules++; @@ -122,7 +122,7 @@ int sched_run(void) return 1; } -#if SCHEDSTATISTICS +#ifdef MODULE_SCHEDSTATISTICS void sched_register_cb(void (*callback)(uint32_t, uint32_t)) { sched_cb = callback; diff --git a/core/thread.c b/core/thread.c index 618c3d1f86..5d4a5ed469 100644 --- a/core/thread.c +++ b/core/thread.c @@ -29,7 +29,6 @@ #include "debug.h" #include "kernel_internal.h" #include "bitarithm.h" -#include "hwtimer.h" #include "sched.h" volatile tcb_t *thread_get(kernel_pid_t pid)