diff options
author | Giovanni Di Sirio <gdisirio@gmail.com> | 2017-10-12 13:31:42 +0000 |
---|---|---|
committer | Giovanni Di Sirio <gdisirio@gmail.com> | 2017-10-12 13:31:42 +0000 |
commit | 4d0b8bdf6e8c27242b38f69c0831eb2a0ddb689f (patch) | |
tree | 7288ed8f896b3b7852e736657e5edbcb7da81cae /os | |
parent | d8b32d7f63c8453135249734f8b542856947e83a (diff) | |
download | ChibiOS-4d0b8bdf6e8c27242b38f69c0831eb2a0ddb689f.tar.gz ChibiOS-4d0b8bdf6e8c27242b38f69c0831eb2a0ddb689f.tar.bz2 ChibiOS-4d0b8bdf6e8c27242b38f69c0831eb2a0ddb689f.zip |
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
Diffstat (limited to 'os')
-rw-r--r-- | os/rt/include/chtime.h | 23 | ||||
-rw-r--r-- | os/rt/include/chvt.h | 8 | ||||
-rw-r--r-- | os/rt/src/chvt.c | 27 |
3 files changed, 43 insertions, 15 deletions
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 */
}
|