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
This commit is contained in:
parent
d8b32d7f63
commit
4d0b8bdf6e
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
# Compiler options here.
|
# Compiler options here.
|
||||||
ifeq ($(USE_OPT),)
|
ifeq ($(USE_OPT),)
|
||||||
USE_OPT = -O0 -ggdb -fomit-frame-pointer -falign-functions=16
|
USE_OPT = -O2 -ggdb -fomit-frame-pointer -falign-functions=16
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# C specific options here (added to USE_OPT).
|
# C specific options here (added to USE_OPT).
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
* @note Not all functions accept @p TIME_IMMEDIATE as timeout parameter,
|
* @note Not all functions accept @p TIME_IMMEDIATE as timeout parameter,
|
||||||
* see the specific function documentation.
|
* 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
|
* @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,
|
* @note Not all functions accept @p TIME_INFINITE as timeout parameter,
|
||||||
* see the specific function documentation.
|
* see the specific function documentation.
|
||||||
*/
|
*/
|
||||||
#define TIME_INFINITE ((sysinterval_t)-1)
|
#define TIME_INFINITE ((sysinterval_t)-1)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Maximum interval constant usable as timeout.
|
* @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.
|
* @brief Type of time interval.
|
||||||
* @note It is selectable in configuration between 16, 32 or 64 bits
|
* @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;
|
typedef uint64_t sysinterval_t;
|
||||||
#elif CH_CFG_ST_RESOLUTION == 32
|
#elif CH_CFG_INTERVALS_SIZE == 32
|
||||||
typedef uint32_t sysinterval_t;
|
typedef uint32_t sysinterval_t;
|
||||||
#elif CH_CFG_ST_RESOLUTION == 16
|
#elif CH_CFG_INTERVALS_SIZE == 16
|
||||||
typedef uint16_t sysinterval_t;
|
typedef uint16_t sysinterval_t;
|
||||||
#endif
|
#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;
|
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");
|
"conversion overflow");
|
||||||
|
|
||||||
return (sysinterval_t)ticks;
|
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) +
|
ticks = (((time_conv_t)msec * (time_conv_t)CH_CFG_ST_FREQUENCY) +
|
||||||
(time_conv_t)999) / (time_conv_t)1000;
|
(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");
|
"conversion overflow");
|
||||||
|
|
||||||
return (sysinterval_t)ticks;
|
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) +
|
ticks = (((time_conv_t)usec * (time_conv_t)CH_CFG_ST_FREQUENCY) +
|
||||||
(time_conv_t)999999) / (time_conv_t)1000000;
|
(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");
|
"conversion overflow");
|
||||||
|
|
||||||
return (sysinterval_t)ticks;
|
return (sysinterval_t)ticks;
|
||||||
|
|
|
@ -72,7 +72,7 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
void _vt_init(void);
|
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);
|
vtfunc_t vtfunc, void *par);
|
||||||
void chVTDoResetI(virtual_timer_t *vtp);
|
void chVTDoResetI(virtual_timer_t *vtp);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -447,6 +447,12 @@ static inline void chVTDoTickI(void) {
|
||||||
if (delta < (sysinterval_t)CH_CFG_ST_TIMEDELTA) {
|
if (delta < (sysinterval_t)CH_CFG_ST_TIMEDELTA) {
|
||||||
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));
|
port_timer_set_alarm(chTimeAddX(now, delta));
|
||||||
|
|
||||||
chDbgAssert(chTimeDiffX(ch.vtlist.lasttime, chVTGetSystemTimeX()) <=
|
chDbgAssert(chTimeDiffX(ch.vtlist.lasttime, chVTGetSystemTimeX()) <=
|
||||||
|
|
|
@ -146,9 +146,18 @@ void chVTDoSetI(virtual_timer_t *vtp, sysinterval_t delay,
|
||||||
p = p->next;
|
p = p->next;
|
||||||
}
|
}
|
||||||
else if (delta < p->delta) {
|
else if (delta < p->delta) {
|
||||||
/* A small delay that will become the first element in the delta list
|
sysinterval_t deadline_delta;
|
||||||
and next deadline.*/
|
|
||||||
port_timer_set_alarm(chTimeAddX(ch.vtlist.lasttime, 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 */
|
#else /* CH_CFG_ST_TIMEDELTA == 0 */
|
||||||
|
@ -207,7 +216,7 @@ void chVTDoResetI(virtual_timer_t *vtp) {
|
||||||
is the last of the list, restoring it.*/
|
is the last of the list, restoring it.*/
|
||||||
ch.vtlist.delta = (sysinterval_t)-1;
|
ch.vtlist.delta = (sysinterval_t)-1;
|
||||||
#else /* CH_CFG_ST_TIMEDELTA > 0 */
|
#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
|
/* If the timer is not the first of the list then it is simply unlinked
|
||||||
else the operation is more complex.*/
|
else the operation is more complex.*/
|
||||||
|
@ -263,7 +272,15 @@ void chVTDoResetI(virtual_timer_t *vtp) {
|
||||||
delta = (systime_t)CH_CFG_ST_TIMEDELTA;
|
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 */
|
#endif /* CH_CFG_ST_TIMEDELTA > 0 */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue