diff --git a/arch/Kconfig b/arch/Kconfig index 7cb6af18657..71049ff51ba 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -59,6 +59,7 @@ config ARCH_SH config ARCH_SIM bool "Simulation" + select ARCH_HAVE_TICKLESS ---help--- Linux/Cywgin user-mode simulation. diff --git a/arch/sim/src/up_idle.c b/arch/sim/src/up_idle.c index 8d04000c4cb..783b57eeabd 100644 --- a/arch/sim/src/up_idle.c +++ b/arch/sim/src/up_idle.c @@ -1,5 +1,5 @@ /**************************************************************************** - * up_idle.c + * arch/sim/src/up_idle.c * * Copyright (C) 2007-2009, 2011-2012, 2014 Gregory Nutt. All rights reserved. * Author: Gregory Nutt diff --git a/arch/sim/src/up_tickless.c b/arch/sim/src/up_tickless.c index 56202e7c1e6..57a7935347f 100644 --- a/arch/sim/src/up_tickless.c +++ b/arch/sim/src/up_tickless.c @@ -1,5 +1,5 @@ /**************************************************************************** - * arch/sim/up_tickless.c + * arch/sim/src/up_tickless.c * * Copyright (C) 2014 Gregory Nutt. All rights reserved. * Author: Gregory Nutt @@ -41,13 +41,11 @@ * * void up_timer_initialize(void): Initializes the timer facilities. Called * early in the intialization sequence (by up_intialize()). - * int up_timer_gettime(FAR struct timespec *tp): Returns the current + * int up_timer_gettime(FAR struct timespec *ts): Returns the current * time from the platform specific time source. * int up_timer_cancel(void): Cancels the interval timer. - * int up_timer_start(FAR const struct timespec *tp): Start (or re-starts) + * int up_timer_start(FAR const struct timespec *ts): Start (or re-starts) * the interval timer. - * int up_timer_resolution(FAR struct timespec *tp): Returns the - * resolution of the interval timer. * * The RTOS will provide the following interfaces for use by the platform- * specific interval timer implementation: @@ -138,17 +136,21 @@ void up_timer_initialize(void) * * Description: * Return the elapsed time since power-up (or, more correctly, since - * up_timer_initialize() was called). This function is functionally equivalent - * to: + * up_timer_initialize() was called). This function is functionally + * equivalent to: * - * int clock_gettime(clockid_t clockid, FAR struct timespec *tp); + * int clock_gettime(clockid_t clockid, FAR struct timespec *ts); * * when clockid is CLOCK_MONOTONIC. * + * This function provides the basis for reporting the current time and + * also is used to eliminate error build-up from small erros in interval + * time calculations. + * * Provided by platform-specific code and called from the RTOS base code. * * Input Parameters: - * tp - Provides the location in which to return the up-time. + * ts - Provides the location in which to return the up-time. * * Returned Value: * Zero (OK) is returned on success; a negated errno value is returned on @@ -162,10 +164,10 @@ void up_timer_initialize(void) * ****************************************************************************/ -int up_timer_gettime(FAR struct timespec *tp) +int up_timer_gettime(FAR struct timespec *ts) { - tp->tv_sec = g_elapsed_time.tv_sec; - tp->tv_nsec = g_elapsed_time.tv_nsec; + ts->tv_sec = g_elapsed_time.tv_sec; + ts->tv_nsec = g_elapsed_time.tv_nsec; return OK; } @@ -173,12 +175,21 @@ int up_timer_gettime(FAR struct timespec *tp) * Name: up_timer_cancel * * Description: - * Cancel the interval timer. up_timer_expiration() will not be called. + * Cancel the interval timer and return the time remaining on the timer. + * These two steps need to be as nearly atomic as possible. + * up_timer_expiration() will not be called unless the timer is restarted + * with up_timer_start(). + * + * If, as a race condition, the timer has already expired when this + * function is called, then that pending interrupt must be cleared so + * that up_timer_start() and the remaining time of zero should be + * returned. * * Provided by platform-specific code and called from the RTOS base code. * * Input Parameters: - * None + * ts - Location to return the remaining time. Zero should be returned + * if the timer is not active. * * Returned Value: * Zero (OK) is returned on success; a negated errno value is returned on @@ -192,8 +203,23 @@ int up_timer_gettime(FAR struct timespec *tp) ****************************************************************************/ #ifdef CONFIG_SCHED_TICKLESS -int up_timer_cancel(void) +int up_timer_cancel(FAR struct timespec *ts) { + /* Return the time remaining on the simulated timer */ + + if (g_timer_active) + { + ts->tv_sec = g_interval_delay.tv_nsec; + ts->tv_nsec = g_interval_delay.tv_sec; + } + else + { + ts->tv_sec = 0; + ts->tv_nsec = 0; + } + + /* Disable and reset the simulated timer */ + g_interval_delay.tv_nsec = 0; g_interval_delay.tv_sec = 0; g_timer_active = false; @@ -211,7 +237,7 @@ int up_timer_cancel(void) * Provided by platform-specific code and called from the RTOS base code. * * Input Parameters: - * tp - Provides the time interval until up_timer_expiration() is called. + * ts - Provides the time interval until up_timer_expiration() is called. * * Returned Value: * Zero (OK) is returned on success; a negated errno value is returned on @@ -225,82 +251,14 @@ int up_timer_cancel(void) ****************************************************************************/ #ifdef CONFIG_SCHED_TICKLESS -int up_timer_start(FAR const struct timespec *tp) +int up_timer_start(FAR const struct timespec *ts) { - g_interval_delay.tv_nsec = tp->tv_nsec; - g_interval_delay.tv_sec = tp->tv_sec; + g_interval_delay.tv_nsec = ts->tv_nsec; + g_interval_delay.tv_sec = ts->tv_sec; g_timer_active = true; } #endif -/**************************************************************************** - * Name: up_timer_remaining - * - * Description: - * Return the time remaining until the next timer expiratino. - * - * Provided by platform-specific code and called from the RTOS base code. - * - * Input Parameters: - * tp - Location to return the remaining time. Zero should be returned - * if the timer is not active. - * - * Returned Value: - * Zero (OK) is returned on success; a negated errno value is returned on - * any failure. - * - * Assumptions: - * May be called from interrupt level handling or from the normal tasking - * level. Interrupts may need to be disabled internally to assure - * non-reentrancy. - * - ****************************************************************************/ - -int up_timer_remaining(FAR struct timespec *tp) -{ - if (g_timer_active) - { - tp->tv_sec = g_interval_delay.tv_nsec; - tp->tv_nsec = g_interval_delay.tv_sec; - } - else - { - tp->tv_sec = 0; - tp->tv_nsec = 0; - } - - return OK; -} - -/**************************************************************************** - * Name: up_timer_resolution - * - * Description: - * Returns the resolution of the interval timer. This defines the minimal - * time separation between two events and is used for scheduling and for - * setting up timed events. - * - * Provided by platform-specific code and called from the RTOS base code. - * - * Input Parameters: - * tp - Provides the location in which to return the timer resolution. - * - * Returned Value: - * - * Assumptions: - * May be called from interrupt level handling or from the normal tasking - * level. Interrupts may need to be disabled internally to assure - * non-reentrancy. - * - ****************************************************************************/ - -int up_timer_resolution(FAR struct timespec *tp) -{ - tp->tv_sec = TICK_SEC; - tp->tv_nsec = TICK_NSEC; - return 0; -} - /**************************************************************************** * Name: up_timer_update *