aboutsummaryrefslogtreecommitdiffstats
path: root/os/nil
diff options
context:
space:
mode:
authorGiovanni Di Sirio <gdisirio@gmail.com>2017-10-18 09:29:23 +0000
committerGiovanni Di Sirio <gdisirio@gmail.com>2017-10-18 09:29:23 +0000
commitc44074d076c53e64562dec1139347e8e326fbc49 (patch)
treeef80500894850c9ba22e6488a4f4ea524e69423b /os/nil
parent3c40945fea5379db8ccfa06aef0bd9cfa1e878fd (diff)
downloadChibiOS-c44074d076c53e64562dec1139347e8e326fbc49.tar.gz
ChibiOS-c44074d076c53e64562dec1139347e8e326fbc49.tar.bz2
ChibiOS-c44074d076c53e64562dec1139347e8e326fbc49.zip
NIL adapted to the new API.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@10846 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/nil')
-rw-r--r--os/nil/include/ch.h205
-rw-r--r--os/nil/src/ch.c47
2 files changed, 162 insertions, 90 deletions
diff --git a/os/nil/include/ch.h b/os/nil/include/ch.h
index d16414402..f413585af 100644
--- a/os/nil/include/ch.h
+++ b/os/nil/include/ch.h
@@ -94,13 +94,23 @@
* @note Not all functions accept @p TIME_IMMEDIATE as timeout parameter,
* see the specific function documentation.
*/
-#define TIME_IMMEDIATE ((systime_t)-1)
+#define TIME_IMMEDIATE ((sysinterval_t)-1)
/**
* @brief Infinite time specification for all functions with a timeout
* specification.
*/
-#define TIME_INFINITE ((systime_t)0)
+#define TIME_INFINITE ((sysinterval_t)0)
+
+/**
+ * @brief Maximum interval constant usable as timeout.
+ */
+#define TIME_MAX_INTERVAL ((sysinterval_t)-2)
+
+/**
+ * @brief Maximum system of system time before it wraps.
+ */
+#define TIME_MAX_SYSTIME ((systime_t)-1)
/** @} */
/**
@@ -457,13 +467,30 @@
/* Module data structures and types. */
/*===========================================================================*/
+#if (CH_CFG_ST_RESOLUTION == 32) || defined(__DOXYGEN__)
/**
* @brief Type of system time.
+ * @note It is selectable in configuration between 16 or 32 bits.
*/
-#if (CH_CFG_ST_RESOLUTION == 32) || defined(__DOXYGEN__)
typedef uint32_t systime_t;
+
+/**
+ * @brief Type of time interval.
+ * @note It is selectable in configuration between 16 or 32 bits.
+ */
+typedef uint32_t sysinterval_t;
+
+/**
+ * @brief Type of time conversion variable.
+ * @note This type must have double width than other time types, it is
+ * only used internally for conversions.
+ */
+typedef uint64_t time_conv_t;
+
#else
typedef uint16_t systime_t;
+typedef uint16_t sysinterval_t;
+typedef uint32_t time_conv_t;
#endif
/**
@@ -541,7 +568,7 @@ struct nil_thread {
eventmask_t ewmask; /**< @brief Enabled events mask. */
#endif
} u1;
- volatile systime_t timeout; /**< @brief Timeout counter, zero
+ volatile sysinterval_t timeout; /**< @brief Timeout counter, zero
if disabled. */
#if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__)
eventmask_t epmask; /**< @brief Pending events mask. */
@@ -827,91 +854,110 @@ struct nil_system {
* @{
*/
/**
- * @brief Seconds to system ticks.
+ * @brief Seconds to time interval.
* @details Converts from seconds to system ticks number.
* @note The result is rounded upward to the next tick boundary.
+ * @note Use of this macro for large values is not secure because
+ * integer overflows, make sure your value can be correctly
+ * converted.
*
- * @param[in] sec number of seconds
+ * @param[in] secs number of seconds
* @return The number of ticks.
*
* @api
*/
-#define S2ST(sec) \
- ((systime_t)((uint32_t)(sec) * (uint32_t)CH_CFG_ST_FREQUENCY))
+#define TIME_S2I(secs) \
+ ((sysinterval_t)((time_conv_t)(secs) * (time_conv_t)CH_CFG_ST_FREQUENCY))
/**
- * @brief Milliseconds to system ticks.
+ * @brief Milliseconds to time interval.
* @details Converts from milliseconds to system ticks number.
* @note The result is rounded upward to the next tick boundary.
+ * @note Use of this macro for large values is not secure because
+ * integer overflows, make sure your value can be correctly
+ * converted.
*
- * @param[in] msec number of milliseconds
+ * @param[in] msecs number of milliseconds
* @return The number of ticks.
*
* @api
*/
-#define MS2ST(msec) \
- ((systime_t)(((((uint32_t)(msec)) * \
- ((uint32_t)CH_CFG_ST_FREQUENCY)) + 999UL) / 1000UL))
+#define TIME_MS2I(msecs) \
+ ((sysinterval_t)((((time_conv_t)(msecs) * \
+ (time_conv_t)CH_CFG_ST_FREQUENCY) + \
+ (time_conv_t)999) / (time_conv_t)1000))
/**
- * @brief Microseconds to system ticks.
+ * @brief Microseconds to time interval.
* @details Converts from microseconds to system ticks number.
* @note The result is rounded upward to the next tick boundary.
+ * @note Use of this macro for large values is not secure because
+ * integer overflows, make sure your value can be correctly
+ * converted.
*
- * @param[in] usec number of microseconds
+ * @param[in] usecs number of microseconds
* @return The number of ticks.
*
* @api
*/
-#define US2ST(usec) \
- ((systime_t)(((((uint32_t)(usec)) * \
- ((uint32_t)CH_CFG_ST_FREQUENCY)) + 999999UL) / 1000000UL))
-/** @} */
+#define TIME_US2I(usecs) \
+ ((sysinterval_t)((((time_conv_t)(usecs) * \
+ (time_conv_t)CH_CFG_ST_FREQUENCY) + \
+ (time_conv_t)999999) / (time_conv_t)1000000))
/**
- * @name Time conversion utilities for the realtime counter
- * @{
- */
-/**
- * @brief Seconds to realtime counter.
- * @details Converts from seconds to realtime counter cycles.
- * @note The macro assumes that @p freq >= @p 1.
+ * @brief Time interval to seconds.
+ * @details Converts from system ticks number to seconds.
+ * @note The result is rounded up to the next second boundary.
+ * @note Use of this macro for large values is not secure because
+ * integer overflows, make sure your value can be correctly
+ * converted.
*
- * @param[in] freq clock frequency, in Hz, of the realtime counter
- * @param[in] sec number of seconds
- * @return The number of cycles.
+ * @param[in] interval interval in ticks
+ * @return The number of seconds.
*
* @api
*/
-#define S2RTC(freq, sec) ((freq) * (sec))
+#define TIME_I2S(interval) \
+ (time_secs_t)(((time_conv_t)(interval) + \
+ (time_conv_t)CH_CFG_ST_FREQUENCY - \
+ (time_conv_t)1) / (time_conv_t)CH_CFG_ST_FREQUENCY)
/**
- * @brief Milliseconds to realtime counter.
- * @details Converts from milliseconds to realtime counter cycles.
- * @note The result is rounded upward to the next millisecond boundary.
- * @note The macro assumes that @p freq >= @p 1000.
+ * @brief Time interval to milliseconds.
+ * @details Converts from system ticks number to milliseconds.
+ * @note The result is rounded up to the next millisecond boundary.
+ * @note Use of this macro for large values is not secure because
+ * integer overflows, make sure your value can be correctly
+ * converted.
*
- * @param[in] freq clock frequency, in Hz, of the realtime counter
- * @param[in] msec number of milliseconds
- * @return The number of cycles.
+ * @param[in] interval interval in ticks
+ * @return The number of milliseconds.
*
* @api
*/
-#define MS2RTC(freq, msec) (rtcnt_t)((((freq) + 999UL) / 1000UL) * (msec))
+#define TIME_I2MS(interval) \
+ (time_msecs_t)((((time_conv_t)(interval) * (time_conv_t)1000) + \
+ (time_conv_t)CH_CFG_ST_FREQUENCY - (time_conv_t)1) / \
+ (time_conv_t)CH_CFG_ST_FREQUENCY)
/**
- * @brief Microseconds to realtime counter.
- * @details Converts from microseconds to realtime counter cycles.
- * @note The result is rounded upward to the next microsecond boundary.
- * @note The macro assumes that @p freq >= @p 1000000.
+ * @brief Time interval to microseconds.
+ * @details Converts from system ticks number to microseconds.
+ * @note The result is rounded up to the next microsecond boundary.
+ * @note Use of this macro for large values is not secure because
+ * integer overflows, make sure your value can be correctly
+ * converted.
*
- * @param[in] freq clock frequency, in Hz, of the realtime counter
- * @param[in] usec number of microseconds
- * @return The number of cycles.
+ * @param[in] interval interval in ticks
+ * @return The number of microseconds.
*
* @api
*/
-#define US2RTC(freq, usec) (rtcnt_t)((((freq) + 999999UL) / 1000000UL) * (usec))
+#define TIME_I2US(interval) \
+ (time_msecs_t)((((time_conv_t)(interval) * (time_conv_t)1000000) + \
+ (time_conv_t)CH_CFG_ST_FREQUENCY - (time_conv_t)1) / \
+ (time_conv_t)CH_CFG_ST_FREQUENCY)
/** @} */
/**
@@ -1104,11 +1150,11 @@ struct nil_system {
* system clock.
* @note The maximum specified value is implementation dependent.
*
- * @param[in] sec time in seconds, must be different from zero
+ * @param[in] secs time in seconds, must be different from zero
*
* @api
*/
-#define chThdSleepSeconds(sec) chThdSleep(S2ST(sec))
+#define chThdSleepSeconds(secs) chThdSleep(TIME_S2I(secs))
/**
* @brief Delays the invoking thread for the specified number of
@@ -1117,11 +1163,11 @@ struct nil_system {
* system clock.
* @note The maximum specified value is implementation dependent.
*
- * @param[in] msec time in milliseconds, must be different from zero
+ * @param[in] msecs time in milliseconds, must be different from zero
*
* @api
*/
-#define chThdSleepMilliseconds(msec) chThdSleep(MS2ST(msec))
+#define chThdSleepMilliseconds(msecs) chThdSleep(TIME_MS2I(msecs))
/**
* @brief Delays the invoking thread for the specified number of
@@ -1130,11 +1176,11 @@ struct nil_system {
* system clock.
* @note The maximum specified value is implementation dependent.
*
- * @param[in] usec time in microseconds, must be different from zero
+ * @param[in] usecs time in microseconds, must be different from zero
*
* @api
*/
-#define chThdSleepMicroseconds(usec) chThdSleep(US2ST(usec))
+#define chThdSleepMicroseconds(usecs) chThdSleep(TIME_US2I(usecs))
/**
* @brief Suspends the invoking thread for the specified time.
@@ -1143,7 +1189,8 @@ struct nil_system {
*
* @sclass
*/
-#define chThdSleepS(timeout) (void) chSchGoSleepTimeoutS(NIL_STATE_SLEEPING, timeout)
+#define chThdSleepS(timeout) \
+ (void) chSchGoSleepTimeoutS(NIL_STATE_SLEEPING, timeout)
/**
* @brief Suspends the invoking thread until the system time arrives to the
@@ -1154,8 +1201,8 @@ struct nil_system {
* @sclass
*/
#define chThdSleepUntilS(abstime) \
- (void) chSchGoSleepTimeoutS(NIL_STATE_SLEEPING, (abstime) - \
- chVTGetSystemTimeX())
+ (void) chSchGoSleepTimeoutS(NIL_STATE_SLEEPING, \
+ chTimeDiffX(chVTGetSystemTimeX(), (abstime)))
/**
* @brief Initializes a threads queue object.
@@ -1275,13 +1322,36 @@ struct nil_system {
* @xclass
*/
#define chVTTimeElapsedSinceX(start) \
- ((systime_t)(chVTGetSystemTimeX() - (start)))
+ chTimeDiffX((start), chVTGetSystemTimeX())
+
+/**
+ * @brief Adds an interval to a system time returning a system time.
+ *
+ * @param[in] systime base system time
+ * @param[in] interval interval to be added
+ * @return The new system time.
+ *
+ * @xclass
+ */
+#define chTimeAddX(systime, interval) \
+ ((systime_t)(systime) + (systime_t)(interval))
+
+/**
+ * @brief Subtracts two system times returning an interval.
+ *
+ * @param[in] start first system time
+ * @param[in] end second system time
+ * @return The interval representing the time difference.
+ *
+ * @xclass
+ */
+#define chTimeDiffX(start, end) \
+ ((sysinterval_t)((systime_t)((systime_t)(end) - (systime_t)(start))))
/**
- * @brief Checks if the specified time is within the specified time window.
+ * @brief Checks if the specified time is within the specified time range.
* @note When start==end then the function returns always true because the
* whole time range is specified.
- * @note This function can be called from any context.
*
* @param[in] time the time to be verified
* @param[in] start the start of the time window (inclusive)
@@ -1291,8 +1361,9 @@ struct nil_system {
*
* @xclass
*/
-#define chVTIsTimeWithinX(time, start, end) \
- ((bool)((systime_t)((time) - (start)) < (systime_t)((end) - (start))))
+#define chTimeIsInRangeX(time, start, end) \
+ ((bool)(((systime_t)(time) - (systime_t)(start)) < \
+ ((systime_t)(end) - (systime_t)(start))))
/**
* @brief Function parameters check.
@@ -1388,18 +1459,18 @@ extern "C" {
bool chSchIsPreemptionRequired(void);
void chSchDoReschedule(void);
void chSchRescheduleS(void);
- msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t timeout);
- msg_t chThdSuspendTimeoutS(thread_reference_t *trp, systime_t timeout);
+ msg_t chSchGoSleepTimeoutS(tstate_t newstate, sysinterval_t timeout);
+ msg_t chThdSuspendTimeoutS(thread_reference_t *trp, sysinterval_t timeout);
void chThdResumeI(thread_reference_t *trp, msg_t msg);
- void chThdSleep(systime_t timeout);
+ void chThdSleep(sysinterval_t timeout);
void chThdSleepUntil(systime_t abstime);
- msg_t chThdEnqueueTimeoutS(threads_queue_t *tqp, systime_t timeout);
+ msg_t chThdEnqueueTimeoutS(threads_queue_t *tqp, sysinterval_t timeout);
void chThdDoDequeueNextI(threads_queue_t *tqp, msg_t msg);
void chThdDequeueNextI(threads_queue_t *tqp, msg_t msg);
void chThdDequeueAllI(threads_queue_t *tqp, msg_t msg);
#if CH_CFG_USE_SEMAPHORES == TRUE
- msg_t chSemWaitTimeout(semaphore_t *sp, systime_t timeout);
- msg_t chSemWaitTimeoutS(semaphore_t *sp, systime_t timeout);
+ msg_t chSemWaitTimeout(semaphore_t *sp, sysinterval_t timeout);
+ msg_t chSemWaitTimeoutS(semaphore_t *sp, sysinterval_t timeout);
void chSemSignal(semaphore_t *sp);
void chSemSignalI(semaphore_t *sp);
void chSemReset(semaphore_t *sp, cnt_t n);
@@ -1408,7 +1479,7 @@ extern "C" {
#if CH_CFG_USE_EVENTS == TRUE
void chEvtSignal(thread_t *tp, eventmask_t mask);
void chEvtSignalI(thread_t *tp, eventmask_t mask);
- eventmask_t chEvtWaitAnyTimeout(eventmask_t mask, systime_t timeout);
+ eventmask_t chEvtWaitAnyTimeout(eventmask_t mask, sysinterval_t timeout);
#endif
#if CH_DBG_SYSTEM_STATE_CHECK == TRUE
void _dbg_check_disable(void);
diff --git a/os/nil/src/ch.c b/os/nil/src/ch.c
index db811f7b2..2c9a61279 100644
--- a/os/nil/src/ch.c
+++ b/os/nil/src/ch.c
@@ -322,12 +322,12 @@ void chSysTimerHandlerI(void) {
nil.systime++;
do {
/* Is the thread in a wait state with timeout?.*/
- if (tp->timeout > (systime_t)0) {
+ if (tp->timeout > (sysinterval_t)0) {
chDbgAssert(!NIL_THD_IS_READY(tp), "is ready");
/* Did the timer reach zero?*/
- if (--tp->timeout == (systime_t)0) {
+ if (--tp->timeout == (sysinterval_t)0) {
/* Timeout on queues/semaphores requires a special handling because
the counter must be incremented.*/
/*lint -save -e9013 [15.7] There is no else because it is not needed.*/
@@ -349,24 +349,25 @@ void chSysTimerHandlerI(void) {
} while (tp < &nil.threads[CH_CFG_NUM_THREADS]);
#else
thread_t *tp = &nil.threads[0];
- systime_t next = (systime_t)0;
+ sysinterval_t next = (sysinterval_t)0;
chDbgAssert(nil.nexttime == port_timer_get_alarm(), "time mismatch");
do {
- systime_t timeout = tp->timeout;
+ sysinterval_t timeout = tp->timeout;
/* Is the thread in a wait state with timeout?.*/
- if (timeout > (systime_t)0) {
+ if (timeout > (sysinterval_t)0) {
chDbgAssert(!NIL_THD_IS_READY(tp), "is ready");
- chDbgAssert(timeout >= (nil.nexttime - nil.lasttime), "skipped one");
+ chDbgAssert(timeout >= chTimeDiffX(nil.lasttime, nil.nexttime),
+ "skipped one");
/* The volatile field is updated once, here.*/
- timeout -= nil.nexttime - nil.lasttime;
+ timeout -= chTimeDiffX(nil.lasttime, nil.nexttime);
tp->timeout = timeout;
- if (timeout == (systime_t)0) {
+ if (timeout == (sysinterval_t)0) {
/* Timeout on thread queues requires a special handling because the
counter must be incremented.*/
if (NIL_THD_IS_WTQUEUE(tp)) {
@@ -380,7 +381,7 @@ void chSysTimerHandlerI(void) {
(void) chSchReadyI(tp, MSG_TIMEOUT);
}
else {
- if (timeout <= (systime_t)(next - (systime_t)1)) {
+ if (timeout <= (sysinterval_t)(next - (sysinterval_t)1)) {
next = timeout;
}
}
@@ -394,8 +395,8 @@ void chSysTimerHandlerI(void) {
} while (tp < &nil.threads[CH_CFG_NUM_THREADS]);
nil.lasttime = nil.nexttime;
- if (next > (systime_t)0) {
- nil.nexttime += next;
+ if (next > (sysinterval_t)0) {
+ nil.nexttime = chTimeAddX(nil.nexttime, next);
port_timer_set_alarm(nil.nexttime);
}
else {
@@ -543,7 +544,7 @@ thread_t *chSchReadyI(thread_t *tp, msg_t msg) {
tp->u1.msg = msg;
tp->state = NIL_STATE_READY;
- tp->timeout = (systime_t)0;
+ tp->timeout = (sysinterval_t)0;
if (tp < nil.next) {
nil.next = tp;
}
@@ -616,7 +617,7 @@ void chSchRescheduleS(void) {
*
* @sclass
*/
-msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t timeout) {
+msg_t chSchGoSleepTimeoutS(tstate_t newstate, sysinterval_t timeout) {
thread_t *ntp, *otp = nil.current;
chDbgCheckClassS();
@@ -633,12 +634,12 @@ msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t timeout) {
/* TIMEDELTA makes sure to have enough time to reprogram the timer
before the free-running timer counter reaches the selected timeout.*/
- if (timeout < (systime_t)CH_CFG_ST_TIMEDELTA) {
- timeout = (systime_t)CH_CFG_ST_TIMEDELTA;
+ if (timeout < (sysinterval_t)CH_CFG_ST_TIMEDELTA) {
+ timeout = (sysinterval_t)CH_CFG_ST_TIMEDELTA;
}
/* Absolute time of the timeout event.*/
- abstime = chVTGetSystemTimeX() + timeout;
+ abstime = chTimeAddX(chVTGetSystemTimeX(), timeout);
if (nil.lasttime == nil.nexttime) {
/* Special case, first thread asking for a timeout.*/
@@ -648,7 +649,7 @@ msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t timeout) {
else {
/* Special case, there are already other threads with a timeout
activated, evaluating the order.*/
- if (chVTIsTimeWithinX(abstime, nil.lasttime, nil.nexttime)) {
+ if (chTimeIsInRangeX(abstime, nil.lasttime, nil.nexttime)) {
port_timer_set_alarm(abstime);
nil.nexttime = abstime;
}
@@ -697,7 +698,7 @@ msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t timeout) {
*
* @sclass
*/
-msg_t chThdSuspendTimeoutS(thread_reference_t *trp, systime_t timeout) {
+msg_t chThdSuspendTimeoutS(thread_reference_t *trp, sysinterval_t timeout) {
chDbgAssert(*trp == NULL, "not NULL");
@@ -735,7 +736,7 @@ void chThdResumeI(thread_reference_t *trp, msg_t msg) {
*
* @api
*/
-void chThdSleep(systime_t timeout) {
+void chThdSleep(sysinterval_t timeout) {
chSysLock();
chThdSleepS(timeout);
@@ -780,7 +781,7 @@ void chThdSleepUntil(systime_t abstime) {
*
* @sclass
*/
-msg_t chThdEnqueueTimeoutS(threads_queue_t *tqp, systime_t timeout) {
+msg_t chThdEnqueueTimeoutS(threads_queue_t *tqp, sysinterval_t timeout) {
chDbgCheckClassS();
chDbgCheck(tqp != NULL);
@@ -900,7 +901,7 @@ void chThdDequeueAllI(threads_queue_t *tqp, msg_t msg) {
*
* @api
*/
-msg_t chSemWaitTimeout(semaphore_t *sp, systime_t timeout) {
+msg_t chSemWaitTimeout(semaphore_t *sp, sysinterval_t timeout) {
msg_t msg;
chSysLock();
@@ -929,7 +930,7 @@ msg_t chSemWaitTimeout(semaphore_t *sp, systime_t timeout) {
*
* @sclass
*/
-msg_t chSemWaitTimeoutS(semaphore_t *sp, systime_t timeout) {
+msg_t chSemWaitTimeoutS(semaphore_t *sp, sysinterval_t timeout) {
chDbgCheckClassS();
chDbgCheck(sp != NULL);
@@ -1122,7 +1123,7 @@ void chEvtSignalI(thread_t *tp, eventmask_t mask) {
*
* @api
*/
-eventmask_t chEvtWaitAnyTimeout(eventmask_t mask, systime_t timeout) {
+eventmask_t chEvtWaitAnyTimeout(eventmask_t mask, sysinterval_t timeout) {
thread_t *ctp = nil.current;
eventmask_t m;