From 0d96f5c78e54d267ef1ca230fe20af1ca090e1d6 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 16 Jun 2013 12:21:30 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/kernel_3_dev@5859 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chschd.c | 2 +- os/kernel/src/chthreads.c | 2 +- os/kernel/src/chvt.c | 124 +++++++++++++++++++++++++++------------------- 3 files changed, 75 insertions(+), 53 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index 1106cf03f..285c36ba3 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -189,7 +189,7 @@ msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t time) { chVTSetI(&vt, time, wakeup, currp); chSchGoSleepS(newstate); if (chVTIsArmedI(&vt)) - chVTResetI(&vt); + chVTDoResetI(&vt); } else chSchGoSleepS(newstate); diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index 9f6973c90..7652cbfb1 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -302,7 +302,7 @@ void chThdSleep(systime_t time) { void chThdSleepUntil(systime_t time) { chSysLock(); - if ((time -= chTimeNow()) > 0) + if ((time -= chVTGetSystemTimeI()) > 0) chThdSleepS(time); chSysUnlock(); } diff --git a/os/kernel/src/chvt.c b/os/kernel/src/chvt.c index a8e3ce499..d27f3170c 100644 --- a/os/kernel/src/chvt.c +++ b/os/kernel/src/chvt.c @@ -20,7 +20,7 @@ /** * @file chvt.c - * @brief Time and Virtual Timers related code. + * @brief Time and Virtual Timers module code. * * @addtogroup time * @details Time and Virtual Timers related APIs and services. @@ -29,11 +29,35 @@ #include "ch.h" +/*===========================================================================*/ +/* Module local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module exported variables. */ +/*===========================================================================*/ + /** * @brief Virtual timers delta list header. */ VTList vtlist; +/*===========================================================================*/ +/* Module local types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module exported functions. */ +/*===========================================================================*/ + /** * @brief Virtual Timers initialization. * @note Internal use only. @@ -43,21 +67,37 @@ VTList vtlist; void _vt_init(void) { vtlist.vt_next = vtlist.vt_prev = (void *)&vtlist; - vtlist.vt_time = (systime_t)-1; - vtlist.vt_systime = 0; + vtlist.vt_time = 0; +} + +/** + * @brief Checks if the current system time is within the specified time + * window. + * @note When start==end then the function returns always true because the + * whole time range is specified. + * + * @param[in] start the start of the time window (inclusive) + * @param[in] end the end of the time window (non inclusive) + * @retval TRUE current time within the specified time window. + * @retval FALSE current time not within the specified time window. + * + * @api + */ +bool_t chVTIsSystemTimeWithin(systime_t start, systime_t end) { + + systime_t time = chVTGetSystemTime(); + return end > start ? (time >= start) && (time < end) : + (time >= start) || (time < end); } /** * @brief Enables a virtual timer. + * @details The timer is enabled and programmed to trigger at the absolute + * system time specified as parameter. * @note The associated function is invoked from interrupt context. * * @param[out] vtp the @p VirtualTimer structure pointer - * @param[in] time the number of ticks before the operation timeouts, the - * special values are handled as follow: - * - @a TIME_INFINITE is allowed but interpreted as a - * normal time specification. - * - @a TIME_IMMEDIATE this value is not allowed. - * . + * @param[in] time absolute system time * @param[in] vtfunc the timer callback function. After invoking the * callback the timer is disabled and the structure can * be disposed or reused. @@ -66,31 +106,36 @@ void _vt_init(void) { * * @iclass */ -void chVTSetI(VirtualTimer *vtp, systime_t time, vtfunc_t vtfunc, void *par) { +void chVTSetAbsoluteI(VirtualTimer *vtp, systime_t time, + vtfunc_t vtfunc, void *par) { VirtualTimer *p; + systime_t systime = vtlist.vt_time; chDbgCheckClassI(); - chDbgCheck((vtp != NULL) && (vtfunc != NULL) && (time != TIME_IMMEDIATE), - "chVTSetI"); + chDbgCheck((vtp != NULL) && (vtfunc != NULL), "chVTSetI"); vtp->vt_par = par; vtp->vt_func = vtfunc; - p = vtlist.vt_next; - while (p->vt_time < time) { - time -= p->vt_time; - p = p->vt_next; - } - - vtp->vt_prev = (vtp->vt_next = p)->vt_prev; - vtp->vt_prev->vt_next = p->vt_prev = vtp; vtp->vt_time = time; - if (p != (void *)&vtlist) - p->vt_time -= time; + if (time <= systime) { + p = vtlist.vt_prev; + while ((p->vt_time <= systime) && (p->vt_time > time)) + p = p->vt_prev; + vtp->vt_next = (vtp->vt_prev = p)->vt_next; + vtp->vt_next->vt_prev = p->vt_next = vtp; + } + else { + p = vtlist.vt_next; + while ((p->vt_time > systime) && (p->vt_time < time)) + p = p->vt_next; + vtp->vt_prev = (vtp->vt_next = p)->vt_prev; + vtp->vt_prev->vt_next = p->vt_prev = vtp; + } } /** * @brief Disables a Virtual Timer. - * @note The timer MUST be active when this function is invoked. + * @note The timer is first checked and disabled only if armed. * * @param[in] vtp the @p VirtualTimer structure pointer * @@ -100,35 +145,12 @@ void chVTResetI(VirtualTimer *vtp) { chDbgCheckClassI(); chDbgCheck(vtp != NULL, "chVTResetI"); - chDbgAssert(vtp->vt_func != NULL, - "chVTResetI(), #1", - "timer not set or already triggered"); - - if (vtp->vt_next != (void *)&vtlist) - vtp->vt_next->vt_time += vtp->vt_time; - vtp->vt_prev->vt_next = vtp->vt_next; - vtp->vt_next->vt_prev = vtp->vt_prev; - vtp->vt_func = (vtfunc_t)NULL; -} -/** - * @brief Checks if the current system time is within the specified time - * window. - * @note When start==end then the function returns always true because the - * whole time range is specified. - * - * @param[in] start the start of the time window (inclusive) - * @param[in] end the end of the time window (non inclusive) - * @retval TRUE current time within the specified time window. - * @retval FALSE current time not within the specified time window. - * - * @api - */ -bool_t chTimeIsWithin(systime_t start, systime_t end) { - - systime_t time = chTimeNow(); - return end > start ? (time >= start) && (time < end) : - (time >= start) || (time < end); + if (chVTIsArmedI(vtp)) { + vtp->vt_prev->vt_next = vtp->vt_next; + vtp->vt_next->vt_prev = vtp->vt_prev; + vtp->vt_func = (vtfunc_t)NULL; + } } /** @} */ -- cgit v1.2.3