From 4d0b8bdf6e8c27242b38f69c0831eb2a0ddb689f Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Thu, 12 Oct 2017 13:31:42 +0000 Subject: Added support for "large virtual timers", those allows for intervals greater than the system time capability. To be tested. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/rt5_dev_point1@10814 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/rt/include/chtime.h | 23 ++++++++++++++--------- os/rt/include/chvt.h | 8 +++++++- os/rt/src/chvt.c | 27 ++++++++++++++++++++++----- 3 files changed, 43 insertions(+), 15 deletions(-) (limited to 'os/rt') diff --git a/os/rt/include/chtime.h b/os/rt/include/chtime.h index 046cde224..e2e3402ef 100644 --- a/os/rt/include/chtime.h +++ b/os/rt/include/chtime.h @@ -42,7 +42,7 @@ * @note Not all functions accept @p TIME_IMMEDIATE as timeout parameter, * see the specific function documentation. */ -#define TIME_IMMEDIATE ((sysinterval_t)0) +#define TIME_IMMEDIATE ((sysinterval_t)0) /** * @brief Infinite interval specification for all functions with a timeout @@ -50,12 +50,17 @@ * @note Not all functions accept @p TIME_INFINITE as timeout parameter, * see the specific function documentation. */ -#define TIME_INFINITE ((sysinterval_t)-1) +#define TIME_INFINITE ((sysinterval_t)-1) /** * @brief Maximum interval constant usable as timeout. */ -#define TIME_MAXIMUM ((sysinterval_t)-2) +#define TIME_MAX_INTERVAL ((sysinterval_t)-2) + +/** + * @brief Maximum system of system time before it wraps. + */ +#define TIME_MAX_SYSTIME ((systime_t)-1) /** @} */ /*===========================================================================*/ @@ -141,11 +146,11 @@ typedef uint16_t systime_t; * @brief Type of time interval. * @note It is selectable in configuration between 16, 32 or 64 bits */ -#if (CH_CFG_ST_RESOLUTION == 64) || defined(__DOXYGEN__) +#if (CH_CFG_INTERVALS_SIZE == 64) || defined(__DOXYGEN__) typedef uint64_t sysinterval_t; -#elif CH_CFG_ST_RESOLUTION == 32 +#elif CH_CFG_INTERVALS_SIZE == 32 typedef uint32_t sysinterval_t; -#elif CH_CFG_ST_RESOLUTION == 16 +#elif CH_CFG_INTERVALS_SIZE == 16 typedef uint16_t sysinterval_t; #endif @@ -336,7 +341,7 @@ static inline sysinterval_t chTimeS2I(time_secs_t secs) { ticks = (time_conv_t)secs * (time_conv_t)CH_CFG_ST_FREQUENCY; - chDbgAssert(ticks <= (time_conv_t)TIME_MAXIMUM, + chDbgAssert(ticks <= (time_conv_t)TIME_MAX_INTERVAL, "conversion overflow"); return (sysinterval_t)ticks; @@ -358,7 +363,7 @@ static inline sysinterval_t chTimeMS2I(time_msecs_t msec) { ticks = (((time_conv_t)msec * (time_conv_t)CH_CFG_ST_FREQUENCY) + (time_conv_t)999) / (time_conv_t)1000; - chDbgAssert(ticks <= (time_conv_t)TIME_MAXIMUM, + chDbgAssert(ticks <= (time_conv_t)TIME_MAX_INTERVAL, "conversion overflow"); return (sysinterval_t)ticks; @@ -380,7 +385,7 @@ static inline sysinterval_t chTimeUS2I(time_usecs_t usec) { ticks = (((time_conv_t)usec * (time_conv_t)CH_CFG_ST_FREQUENCY) + (time_conv_t)999999) / (time_conv_t)1000000; - chDbgAssert(ticks <= (time_conv_t)TIME_MAXIMUM, + chDbgAssert(ticks <= (time_conv_t)TIME_MAX_INTERVAL, "conversion overflow"); return (sysinterval_t)ticks; diff --git a/os/rt/include/chvt.h b/os/rt/include/chvt.h index 70a70465e..35bd947e0 100644 --- a/os/rt/include/chvt.h +++ b/os/rt/include/chvt.h @@ -72,7 +72,7 @@ extern "C" { #endif void _vt_init(void); - void chVTDoSetI(virtual_timer_t *vtp, systime_t delay, + void chVTDoSetI(virtual_timer_t *vtp, sysinterval_t delay, vtfunc_t vtfunc, void *par); void chVTDoResetI(virtual_timer_t *vtp); #ifdef __cplusplus @@ -447,6 +447,12 @@ static inline void chVTDoTickI(void) { if (delta < (sysinterval_t)CH_CFG_ST_TIMEDELTA) { delta = (sysinterval_t)CH_CFG_ST_TIMEDELTA; } +#if CH_CFG_INTERVALS_SIZE > CH_CFG_ST_RESOLUTION + /* The delta could be too large for the physical timer to handle.*/ + if (delta > (sysinterval_t)TIME_MAX_SYSTIME) { + delta = (sysinterval_t)TIME_MAX_SYSTIME; + } +#endif port_timer_set_alarm(chTimeAddX(now, delta)); chDbgAssert(chTimeDiffX(ch.vtlist.lasttime, chVTGetSystemTimeX()) <= diff --git a/os/rt/src/chvt.c b/os/rt/src/chvt.c index 4d887b8c4..f627436b4 100644 --- a/os/rt/src/chvt.c +++ b/os/rt/src/chvt.c @@ -146,9 +146,18 @@ void chVTDoSetI(virtual_timer_t *vtp, sysinterval_t delay, p = p->next; } else if (delta < p->delta) { - /* A small delay that will become the first element in the delta list - and next deadline.*/ - port_timer_set_alarm(chTimeAddX(ch.vtlist.lasttime, delta)); + sysinterval_t deadline_delta; + + /* A small delay that will become the first element in the delta list + and next deadline.*/ + deadline_delta = delta; +#if CH_CFG_INTERVALS_SIZE > CH_CFG_ST_RESOLUTION + /* The delta could be too large for the physical timer to handle.*/ + if (deadline_delta > (sysinterval_t)TIME_MAX_SYSTIME) { + deadline_delta = (sysinterval_t)TIME_MAX_SYSTIME; + } +#endif + port_timer_set_alarm(chTimeAddX(ch.vtlist.lasttime, deadline_delta)); } } #else /* CH_CFG_ST_TIMEDELTA == 0 */ @@ -207,7 +216,7 @@ void chVTDoResetI(virtual_timer_t *vtp) { is the last of the list, restoring it.*/ ch.vtlist.delta = (sysinterval_t)-1; #else /* CH_CFG_ST_TIMEDELTA > 0 */ - sysinterval_t nowdelta, delta; + sysinterval_t nowdelta, delta, deadline_delta; /* If the timer is not the first of the list then it is simply unlinked else the operation is more complex.*/ @@ -263,7 +272,15 @@ void chVTDoResetI(virtual_timer_t *vtp) { delta = (systime_t)CH_CFG_ST_TIMEDELTA; } - port_timer_set_alarm(chTimeAddX(ch.vtlist.lasttime, nowdelta + delta)); + /* Next deadline.*/ + deadline_delta = nowdelta + delta; +#if CH_CFG_INTERVALS_SIZE > CH_CFG_ST_RESOLUTION + /* The delta could be too large for the physical timer to handle.*/ + if (deadline_delta > (sysinterval_t)TIME_MAX_SYSTIME) { + deadline_delta = (sysinterval_t)TIME_MAX_SYSTIME; + } +#endif + port_timer_set_alarm(chTimeAddX(ch.vtlist.lasttime, deadline_delta)); #endif /* CH_CFG_ST_TIMEDELTA > 0 */ } -- cgit v1.2.3