diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2014-03-31 09:25:50 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2014-03-31 09:25:50 -0600 |
commit | df394c157f4a0f7e82efa15f873cfe5a05daabae (patch) | |
tree | c6c28f8ee899331e54a984b0da988717d13e7dd1 | |
parent | f469ebe852be64d8839117ee818ede523fc0b99f (diff) | |
download | px4-nuttx-df394c157f4a0f7e82efa15f873cfe5a05daabae.tar.gz px4-nuttx-df394c157f4a0f7e82efa15f873cfe5a05daabae.tar.bz2 px4-nuttx-df394c157f4a0f7e82efa15f873cfe5a05daabae.zip |
Add support for CLOCK_MONOTONIC. From Macs N
-rw-r--r-- | nuttx/ChangeLog | 2 | ||||
-rw-r--r-- | nuttx/include/time.h | 29 | ||||
-rw-r--r-- | nuttx/sched/clock_gettime.c | 78 |
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; } |