summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2014-03-31 09:25:50 -0600
committerGregory Nutt <gnutt@nuttx.org>2014-03-31 09:25:50 -0600
commitdf394c157f4a0f7e82efa15f873cfe5a05daabae (patch)
treec6c28f8ee899331e54a984b0da988717d13e7dd1
parentf469ebe852be64d8839117ee818ede523fc0b99f (diff)
downloadnuttx-df394c157f4a0f7e82efa15f873cfe5a05daabae.tar.gz
nuttx-df394c157f4a0f7e82efa15f873cfe5a05daabae.tar.bz2
nuttx-df394c157f4a0f7e82efa15f873cfe5a05daabae.zip
Add support for CLOCK_MONOTONIC. From Macs N
-rw-r--r--nuttx/ChangeLog2
-rw-r--r--nuttx/include/time.h29
-rw-r--r--nuttx/sched/clock_gettime.c78
3 files changed, 85 insertions, 24 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog
index 71baf68cf..6957d7b9a 100644
--- a/nuttx/ChangeLog
+++ b/nuttx/ChangeLog
@@ -7087,4 +7087,6 @@
* libc/stdio/lib_sccanf.c: Fix a counting error in the return
value from sscanf(). Noted by kfrolov. Also, sscanf() should
return EOF if no values were converted (2014-3-30).
+ * include/time.h and sched/clock_settime(): Add support for
+ CLOCK_REALTIME. From Macs N (2014-3-31).
diff --git a/nuttx/include/time.h b/nuttx/include/time.h
index f89b0ad29..a3b5731e2 100644
--- a/nuttx/include/time.h
+++ b/nuttx/include/time.h
@@ -1,7 +1,7 @@
/********************************************************************************
* include/time.h
*
- * Copyright (C) 2007-2011, 2013 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2007-2011, 2013-2014 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -67,19 +67,23 @@
# define CLOCKS_PER_SEC (100)
#endif
-/* CLOCK_REALTIME refers to the standard time source. For most implementations,
- * the standard time source is the system timer interrupt. However, if the
- * platform supports an RTC, then the standard time source will be the RTC
- * for the clock_gettime() and clock_settime() interfaces (the system timer
- * is still the time source for all of the interfaces).
+/* CLOCK_REALTIME refers to the standard time source. For most
+ * implementations, the standard time source is the system timer interrupt.
+ * However, if the platform supports an RTC, then the standard time source
+ * will be the RTC for the clock_gettime() and clock_settime() interfaces
+ * (the system timer is still the time source for all of the interfaces).
+ *
+ * CLOCK_REALTIME represents the machine's best-guess as to the current
+ * wall-clock, time-of-day time. This means that CLOCK_REALTIME can jump
+ * forward and backward as the system time-of-day clock is changed.
*/
#define CLOCK_REALTIME 0
/* If an RTC is supported, then the non-standard CLOCK_ACTIVETIME is also
- * supported to manage time based on the system timer interrupt separately from
- * the RTC. This may be necessary, for example, in certain cases where the
- * system timer interrupt has been stopped in low power modes.
+ * supported to manage time based on the system timer interrupt separately
+ * from the RTC. This may be necessary, for example, in certain cases where
+ * the system timer interrupt has been stopped in low power modes.
*
* CLOCK_ACTIVETIME is only recognized by clock_gettime() and clock_settime().
*/
@@ -90,6 +94,13 @@
# define CLOCK_ACTIVETIME CLOCK_REALTIME
#endif
+/* Clock that cannot be set and represents monotonic time since some
+ * unspecified starting point. It is not affected by changes in the
+ * system time-of-day clock.
+ */
+
+#define CLOCK_MONOTONIC 2
+
/* This is a flag that may be passed to the timer_settime() function */
#define TIMER_ABSTIME 1
diff --git a/nuttx/sched/clock_gettime.c b/nuttx/sched/clock_gettime.c
index d6772dada..6aa8b44d1 100644
--- a/nuttx/sched/clock_gettime.c
+++ b/nuttx/sched/clock_gettime.c
@@ -1,7 +1,7 @@
/************************************************************************
* sched/clock_gettime.c
*
- * Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2007, 2009, 2011, 2014 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -51,7 +51,7 @@
#include "clock_internal.h"
/************************************************************************
- * Definitions
+ * Pre-processor Definitions
************************************************************************/
/************************************************************************
@@ -101,35 +101,80 @@ int clock_gettime(clockid_t clock_id, struct timespec *tp)
uint32_t secs;
uint32_t nsecs;
#endif
+ uint32_t carry;
int ret = OK;
sdbg("clock_id=%d\n", clock_id);
DEBUGASSERT(tp != NULL);
- /* CLOCK_REALTIME - POSIX demands this to be present. This is the wall
- * time clock.
+ /* CLOCK_MONOTONIC is an optional under POSIX: "If the Monotonic Clock
+ * option is supported, all implementations shall support a clock_id
+ * of CLOCK_MONOTONIC defined in <time.h>. This clock represents the
+ * monotonic clock for the system. For this clock, the value returned
+ * by clock_gettime() represents the amount of time (in seconds and
+ * nanoseconds) since an unspecified point in the past (for example,
+ * system start-up time, or the Epoch). This point does not change
+ * after system start-up time. The value of the CLOCK_MONOTONIC clock
+ * cannot be set via clock_settime(). This function shall fail if it
+ * is invoked with a clock_id argument of CLOCK_MONOTONIC."
+ */
+
+ if (clock_id == CLOCK_MONOTONIC)
+ {
+ /* Get the time since power-on in seconds and milliseconds */
+
+ msecs = MSEC_PER_TICK * g_system_timer;
+ secs = msecs / MSEC_PER_SEC;
+
+ /* Return the elapsed time in seconds and nanoseconds */
+
+ nsecs = (msecs - (secs * MSEC_PER_SEC)) * NSEC_PER_MSEC;
+ if (nsecs > NSEC_PER_SEC)
+ {
+ carry = nsecs / NSEC_PER_SEC;
+ secs += carry;
+ nsecs -= (carry * NSEC_PER_SEC);
+ }
+
+ tp->tv_sec = (time_t)secs;
+ tp->tv_nsec = (long)nsecs;
+ }
+
+ /* CLOCK_REALTIME - POSIX demands this to be present. CLOCK_REALTIME
+ * represents the machine's best-guess as to the current wall-clock,
+ * time-of-day time. This means that CLOCK_REALTIME can jump forward and
+ * backward as the system time-of-day clock is changed.
+ *
+ * If an RTC is supported, then the non-standard CLOCK_ACTIVETIME is also
+ * supported to manage time based on the system timer interrupt separately
+ * from the RTC. This may be necessary, for example, in certain cases where
+ * the system timer interrupt has been stopped in low power modes.
*/
#ifdef CONFIG_RTC
- if (clock_id == CLOCK_REALTIME || clock_id == CLOCK_ACTIVETIME)
+ else if (clock_id == CLOCK_REALTIME || clock_id == CLOCK_ACTIVETIME)
#else
- if (clock_id == CLOCK_REALTIME)
+ else if (clock_id == CLOCK_REALTIME)
#endif
{
- /* Do we have a high-resolution RTC that can provie us with the time? */
+ /* Do we have a high-resolution RTC that can provide us with the time? */
#ifdef CONFIG_RTC_HIRES
if (g_rtc_enabled && clock_id != CLOCK_ACTIVETIME)
{
- /* Yes.. Get the hi-resolution time from the RTC */
+ /* Yes.. Get the hi-resolution time from the RTC unless the caller
+ * has specifically asked for the system timer (CLOCK_ACTIVETIME)
+ */
ret = up_rtc_gettime(tp);
}
else
#endif
{
- /* Get the elapsed time since power up (in milliseconds) biased
- * as appropriate.
+ /* Get the elapsed time since the time-of-day was last set.
+ * g_system_timer provides the number of clock times since
+ * power was applied; the bias value corresponds to the time
+ * when the time-of-day was last set.
*/
msecs = MSEC_PER_TICK * (g_system_timer - g_tickbias);
@@ -146,7 +191,10 @@ int clock_gettime(clockid_t clock_id, struct timespec *tp)
(int)msecs, (int)g_basetime.tv_sec,
(int)nsecs, (int)g_basetime.tv_nsec);
- /* Add the base time to this. */
+ /* Add the base time to this. The base time is the time-of-day
+ * setting. When added to the elapsed time since the time-of-day
+ * was last set, this gives us the current time.
+ */
secs += (uint32_t)g_basetime.tv_sec;
nsecs += (uint32_t)g_basetime.tv_nsec;
@@ -155,9 +203,9 @@ int clock_gettime(clockid_t clock_id, struct timespec *tp)
if (nsecs > NSEC_PER_SEC)
{
- uint32_t dwCarrySecs = nsecs / NSEC_PER_SEC;
- secs += dwCarrySecs;
- nsecs -= (dwCarrySecs * NSEC_PER_SEC);
+ carry = nsecs / NSEC_PER_SEC;
+ secs += carry;
+ nsecs -= (carry * NSEC_PER_SEC);
}
/* And return the result to the caller. */
@@ -172,7 +220,7 @@ int clock_gettime(clockid_t clock_id, struct timespec *tp)
{
sdbg("Returning ERROR\n");
- errno = EINVAL;
+ set_errno(EINVAL);
ret = ERROR;
}