Remove support for UTC time; add support for 64-bit time

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4006 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo
2011-10-02 14:16:30 +00:00
parent 3f4af2fe30
commit d8c4138e74
11 changed files with 181 additions and 319 deletions
+3
View File
@@ -2126,3 +2126,6 @@
time when the MCU is off and also for a low-resolution (1 sec/tick) RTC time when the MCU is off and also for a low-resolution (1 sec/tick) RTC
that can run until 2106 with no overflow. But in this latter case, higher that can run until 2106 with no overflow. But in this latter case, higher
resolution time must come from the system timer. resolution time must come from the system timer.
* CONFIG_SYSTEM_UTC - Removed support for the UTC system timer. It just
doesn't do enough to be worth the CPU cycles or the complexity.
* CONFIG_SYSTEM_TIME16 - Added support for an optional 64-bit system timer.
+15 -51
View File
@@ -1887,6 +1887,9 @@ The system can be re-made subsequently by just typing <code>make</code>.
That timer interrupt runs at rate determined by <code>CONFIG_MSEC_PER_TICKS</code> (default 10 or 100Hz). That timer interrupt runs at rate determined by <code>CONFIG_MSEC_PER_TICKS</code> (default 10 or 100Hz).
The timer generates an interrupt each <code>CONFIG_MSEC_PER_TICKS</code> milliseconds and increments a counter called <code>g_system_timer</code>. The timer generates an interrupt each <code>CONFIG_MSEC_PER_TICKS</code> milliseconds and increments a counter called <code>g_system_timer</code>.
<code>g_system_timer</code> then provides a time-base for calculating <i>up-time</i> and elapsed time intervals in units of <code>CONFIG_MSEC_PER_TICKS</code>. <code>g_system_timer</code> then provides a time-base for calculating <i>up-time</i> and elapsed time intervals in units of <code>CONFIG_MSEC_PER_TICKS</code>.
The range of <code>g_system_timer</code> is, by default, 32-bits.
However, if the MCU supports type <code>long long</code> and <code>CONFIG_SYSTEM_TIME16</code> is selected,
a 64-bit system timer will be supported instead.
</p> </p>
<p><b>System Timer Accuracy</b> <p><b>System Timer Accuracy</b>
On many system, the exact timer interval specified by <code>CONFIG_MSEC_PER_TICKS</code> cannot be achieved due to limitations in frequencies or in dividers. On many system, the exact timer interval specified by <code>CONFIG_MSEC_PER_TICKS</code> cannot be achieved due to limitations in frequencies or in dividers.
@@ -1960,34 +1963,7 @@ else
In this way, the timer interval is controlled from interrupt-to-interrupt to produce an average frequency of exactly 100Hz. In this way, the timer interval is controlled from interrupt-to-interrupt to produce an average frequency of exactly 100Hz.
</p> </p>
<h4>4.1.20.2 UTC Time Representation</h4> <h4>4.1.20.1 Hardware</h4>
<p>
To enable UTC time representation use option:
</p>
<ul><pre>
CONFIG_SYSTEM_UTC=y
</pre></ul>
<p>
which adds the following variables:
</p>
<ul>
<li><code>g_system_utc</code> (seconds, 4 bytes)</li>
<li><code>g_tickcount</code> (timer ticks, 1-2 bytes typically)</li>
</ul>
<p>
and replaces:
</p>
<ul>
<li><code>g_system_timer</code>(4 bytes)</li>
<li><code>g_basetime</code>(8 bytes)</li>
<li><code>g_tickbias</code>(4 bytes)</li>
</ul>
<p>
Otherwise internal time is computed from 32-bit running tick timer
<code>g_systemtimer</code> the start date <code>g_basetime</code> and time offset the <code>g_tickbias</code>.
</p>
<h4>4.1.20.2 Hardware</h4>
<p> <p>
To enable hardware module use the following configuration options: To enable hardware module use the following configuration options:
<p> <p>
@@ -2014,47 +1990,29 @@ CONFIG_SYSTEM_UTC=y
<li><code>up_rtc_time()</code>. UTC time in seconds.</li> <li><code>up_rtc_time()</code>. UTC time in seconds.</li>
<li><code>up_rtc_gettime()</code>. Replacement for <code>g_system_tick</code></li> <li><code>up_rtc_gettime()</code>. Replacement for <code>g_system_tick</code></li>
</ul> </ul>
<p>
This module depends on <code>CONFIG_SYSTEM_UTC=y</code>.
</p>
<h4>4.1.20.3 System Tick and Time</h4> <h4>4.1.20.2 System Tick and Time</h4>
<p> <p>
The system tick is represented by, when <code>CONFIG_SYSTEM_UTC=n</code>: The system tick is represented by::
</p> </p>
<ul> <ul>
<li><code>g_system_timer</code></li> <li><code>g_system_timer</code></li>
</ul> </ul>
<p>
or, when <code>CONFIG_SYSTEM_UTC=y</code>
</p>
<ul>
<li><code>g_tickcount</code></li>
<li><code>g_system_utc</code></li>
</ul>
<p> <p>
Running at rate of system base timer, used for time-slicing, and so forth. Running at rate of system base timer, used for time-slicing, and so forth.
</p> </p>
<p> <p>
If hardware RTC is present (<code>CONFIG_RTC</code>) and and high-resolution timeing If hardware RTC is present (<code>CONFIG_RTC</code>) and and high-resolution timing
is enabled (<code>CONFIG_RTC_HIRES</code>), then after successful is enabled (<code>CONFIG_RTC_HIRES</code>), then after successful
initiliazation variables are overriden by calls to <code>up_rtc_gettime()</code> which is initiliazation variables are overriden by calls to <code>up_rtc_gettime()</code> which is
running continously even in power-down modes. running continously even in power-down modes.
</p> </p>
<p> <p>
In the case of <code>CONFIG_RTC_HIRES</code> is set the <code>g_tickcount</code> and In the case of <code>CONFIG_RTC_HIRES</code> is set the <code>g_system_timer</code>
<code>g_system_utc</code> keep counting at rate of a system timer, which however, is keeps counting at rate of a system timer, which however, is disabled in power-down mode.
disabled in power-down mode.
By comparing this time and RTC (actual time) one may determine the actual system active time. By comparing this time and RTC (actual time) one may determine the actual system active time.
To retrieve that variable use: To retrieve that variable use:
</p> </p>
<ul><pre>
<li><code>clock_gettime(CLOCK_ACTIVETIME, tp)</code>
</pre></ul>
<p>
If the <code>CLOCK_ACTIVETIME</code> time is never set it will serve as power-up time
minus all deep sleeps.
</p>
<h2><a name="exports">4.2 APIs Exported by NuttX to Architecture-Specific Logic</a></h2> <h2><a name="exports">4.2 APIs Exported by NuttX to Architecture-Specific Logic</a></h2>
<p> <p>
@@ -3765,6 +3723,12 @@ build
task name to save in the TCB. Useful if scheduler task name to save in the TCB. Useful if scheduler
instrumentation is selected. Set to zero to disable. instrumentation is selected. Set to zero to disable.
</li> </li>
<li>
<code>CONFIG_SYSTEM_TIME16</code>:
The range of system time is, by default, 32-bits.
However, if the MCU supports type <code>long long</code> and <code>CONFIG_SYSTEM_TIME16</code> is selected,
a 64-bit system timer will be supported instead.
</li>
<li> <li>
<code>CONFIG_START_YEAR</code>, <code>CONFIG_START_MONTH</code>, <code>CONFIG_START_DAY</code> - <code>CONFIG_START_YEAR</code>, <code>CONFIG_START_MONTH</code>, <code>CONFIG_START_DAY</code> -
Used to initialize the internal time logic. Used to initialize the internal time logic.
-1
View File
@@ -269,7 +269,6 @@ CONFIG_WIRELESS=y
CONFIG_RTC=y CONFIG_RTC=y
CONFIG_RTC_HIRES=y CONFIG_RTC_HIRES=y
CONFIG_RTC_FREQUENCY=16384 CONFIG_RTC_FREQUENCY=16384
CONFIG_SYSTEM_UTC=y
# #
# OS support for events # OS support for events
+1 -1
View File
@@ -712,7 +712,7 @@ int sif_main(int argc, char *argv[])
fprintf(stderr, "%s:\tinit\n\tgpio\tA B\n\tpwr\tval\n", argv[0]); fprintf(stderr, "%s:\tinit\n\tgpio\tA B\n\tpwr\tval\n", argv[0]);
struct timespec t_active; struct timespec t_active;
clock_gettime(CLOCK_ACTIVETIME, &t_active); clock_gettime(CLOCK_REALTIME, &t_active);
fprintf(stderr, "rtc time = %u, active = %u / %u, time / systick = %u / %u\n", fprintf(stderr, "rtc time = %u, active = %u / %u, time / systick = %u / %u\n",
up_rtc_time(), t_active.tv_sec, t_active.tv_nsec, up_rtc_time(), t_active.tv_sec, t_active.tv_nsec,
+51 -17
View File
@@ -44,6 +44,7 @@
#include <stdint.h> #include <stdint.h>
#include <time.h> #include <time.h>
#include <nuttx/compiler.h>
/**************************************************************************** /****************************************************************************
* Pro-processor Definitions * Pro-processor Definitions
@@ -63,6 +64,14 @@
# define __HAVE_KERNEL_GLOBALS 0 # define __HAVE_KERNEL_GLOBALS 0
#endif #endif
/* If CONFIG_SYSTEM_TIME64 is selected and the CPU supports long long types,
* then a 64-bit system time will be used.
*/
#ifndef CONFIG_HAVE_LONG_LONG
# undef CONFIG_SYSTEM_TIME64
#endif
/* Timing constants *********************************************************/ /* Timing constants *********************************************************/
#define NSEC_PER_SEC 1000000000 #define NSEC_PER_SEC 1000000000
@@ -126,20 +135,18 @@
*/ */
#if __HAVE_KERNEL_GLOBALS #if __HAVE_KERNEL_GLOBALS
# ifdef CONFIG_SYSTEM_TIME64
extern volatile uint64_t g_system_timer;
#define clock_systimer() (uint32_t)(g_system_timer & 0x00000000ffffffff)
#define clock_systimer64() g_system_timer
# else
extern volatile uint32_t g_system_timer; extern volatile uint32_t g_system_timer;
extern volatile uint32_t g_system_utc;
#if TICK_PER_SEC > 32767
extern volatile uint32_t g_tickcount;
#elif TICK_PER_SEC > 255
extern volatile uint16_t g_tickcount;
#else
extern volatile uint8_t g_tickcount;
#endif
#endif /* __HAVE_KERNEL_GLOBALS */
#if !defined(CONFIG_SYSTEM_UTC) && __HAVE_KERNEL_GLOBALS
#define clock_systimer() g_system_timer #define clock_systimer() g_system_timer
# endif
#endif #endif
/**************************************************************************** /****************************************************************************
@@ -157,10 +164,10 @@ extern "C" {
* Function: clock_systimer * Function: clock_systimer
* *
* Description: * Description:
* Return the current value of the system timer counter. Indirect access * Return the current value of the 32-bit system timer counter. Indirect
* to the system timer counter is required through this function if (1) we * access to the system timer counter is required through this function if
* are using a hardware periodic timer, OR (2) the execution environment * the execution environment does not have direct access to kernel global
* does not have direct access to kernel global data * data
* *
* Parameters: * Parameters:
* None * None
@@ -172,8 +179,35 @@ extern "C" {
* *
****************************************************************************/ ****************************************************************************/
#if defined(CONFIG_SYSTEM_UTC) || !__HAVE_KERNEL_GLOBALS #if !__HAVE_KERNEL_GLOBALS
# ifdef CONFIG_SYSTEM_TIME64
# define clock_systimer() (uint32_t)(clock_systimer64() & 0x00000000ffffffff)
# else
EXTERN uint32_t clock_systimer(void); EXTERN uint32_t clock_systimer(void);
# endif
#endif
/****************************************************************************
* Function: clock_systimer64
*
* Description:
* Return the current value of the 64-bit system timer counter. Indirect
* access to the system timer counter is required through this function if
* the execution environment does not have direct access to kernel global
* data
*
* Parameters:
* None
*
* Return Value:
* The current value of the system timer counter
*
* Assumptions:
*
****************************************************************************/
#if !__HAVE_KERNEL_GLOBALS && defined(CONFIG_SYSTEM_TIME64)
EXTERN uint64_t clock_systimer64(void);
#endif #endif
#undef EXTERN #undef EXTERN
-10
View File
@@ -73,16 +73,6 @@
#define CLOCK_REALTIME 0 #define CLOCK_REALTIME 0
/* Non-standard. Returns active UTC time, which is disabled during
* power down modes. Unit is 1 second.
*/
#ifdef CONFIG_SYSTEM_UTC
# define CLOCK_ACTIVETIME 1
#endif
#define CLOCK_ABSTIME
/* This is a flag that may be passed to the timer_settime() function */ /* This is a flag that may be passed to the timer_settime() function */
#define TIMER_ABSTIME 1 #define TIMER_ABSTIME 1
+42 -91
View File
@@ -91,127 +91,78 @@
int clock_gettime(clockid_t clock_id, struct timespec *tp) int clock_gettime(clockid_t clock_id, struct timespec *tp)
{ {
#ifndef CONFIG_SYSTEM_UTC #ifdef CONFIG_SYSTEM_TIME64
uint64_t msecs;
uint64_t secs;
uint64_t nsecs;
#else
uint32_t msecs; uint32_t msecs;
uint32_t secs; uint32_t secs;
uint32_t nsecs; uint32_t nsecs;
#else
uint32_t system_utc;
uint32_t tickcount;
#endif #endif
#if defined(CONFIG_RTC) || defined(CONFIG_SYSTEM_UTC)
irqstate_t flags;
#endif
int ret = OK; int ret = OK;
sdbg("clock_id=%d\n", clock_id); sdbg("clock_id=%d\n", clock_id);
DEBUGASSERT(tp != NULL);
/* CLOCK_REALTIME - POSIX demands this to be present. This is the wall /* CLOCK_REALTIME - POSIX demands this to be present. This is the wall
* time clock. * time clock.
*/ */
if (clock_id == CLOCK_REALTIME && tp) if (clock_id == CLOCK_REALTIME)
{ {
/* If CONFIG_SYSTEM_UTC is not defined, then we have to get the time /* Do we have a high-resolution RTC that can provie us with the time? */
* from g_system_timer.
*/
#ifndef CONFIG_SYSTEM_UTC
/* Get the elapsed time since power up (in milliseconds) biased
* as appropriate.
*/
msecs = MSEC_PER_TICK * (clock_systimer() - g_tickbias);
sdbg("msecs = %d g_tickbias=%d\n",
(int)msecs, (int)g_tickbias);
/* Get the elapsed time in seconds and nanoseconds. */
secs = msecs / MSEC_PER_SEC;
nsecs = (msecs - (secs * MSEC_PER_SEC)) * NSEC_PER_MSEC;
sdbg("secs = %d + %d nsecs = %d + %d\n",
(int)msecs, (int)g_basetime.tv_sec,
(int)nsecs, (int)g_basetime.tv_nsec);
/* Add the base time to this. */
secs += (uint32_t)g_basetime.tv_sec;
nsecs += (uint32_t)g_basetime.tv_nsec;
/* Handle carry to seconds. */
if (nsecs > NSEC_PER_SEC)
{
uint32_t dwCarrySecs = nsecs / NSEC_PER_SEC;
secs += dwCarrySecs;
nsecs -= (dwCarrySecs * NSEC_PER_SEC);
}
/* And return the result to the caller. */
tp->tv_sec = (time_t)secs;
tp->tv_nsec = (long)nsecs;
#else /* CONFIG_SYSTEM_UTC */
/* CONFIG_SYSTEM_UTC is defined. But we might be able to get the time
* from the hardware if a high resolution RTC is available.
*/
#ifdef CONFIG_RTC_HIRES #ifdef CONFIG_RTC_HIRES
if (g_rtc_enabled) if (g_rtc_enabled)
{ {
/* Get the hi-resolution time from the RTC */ /* Yes.. Get the hi-resolution time from the RTC */
ret = up_rtc_gettime(tp); ret = up_rtc_gettime(tp);
} }
else else
#endif #endif
{ {
/* Disable interrupts while g_system_utc and g_tickcount are sampled /* Get the elapsed time since power up (in milliseconds) biased
* so that we can be assured that g_system_utc and g_tickcount are based * as appropriate.
* at the same point in time.
*/ */
flags = irqsave(); msecs = MSEC_PER_TICK * (g_system_timer - g_tickbias);
system_utc = g_system_utc;
tickcount = g_tickcount;
irqrestore(flags);
tp->tv_sec = system_utc; sdbg("msecs = %d g_tickbias=%d\n",
tp->tv_nsec = tickcount * (1000000000/TICK_PER_SEC); (int)msecs, (int)g_tickbias);
/* Get the elapsed time in seconds and nanoseconds. */
secs = msecs / MSEC_PER_SEC;
nsecs = (msecs - (secs * MSEC_PER_SEC)) * NSEC_PER_MSEC;
sdbg("secs = %d + %d nsecs = %d + %d\n",
(int)msecs, (int)g_basetime.tv_sec,
(int)nsecs, (int)g_basetime.tv_nsec);
/* Add the base time to this. */
secs += (uint32_t)g_basetime.tv_sec;
nsecs += (uint32_t)g_basetime.tv_nsec;
/* Handle carry to seconds. */
if (nsecs > NSEC_PER_SEC)
{
uint32_t dwCarrySecs = nsecs / NSEC_PER_SEC;
secs += dwCarrySecs;
nsecs -= (dwCarrySecs * NSEC_PER_SEC);
}
/* And return the result to the caller. */
tp->tv_sec = (time_t)secs;
tp->tv_nsec = (long)nsecs;
} }
#endif /* CONFIG_SYSTEM_UTC */
sdbg("Returning tp=(%d,%d)\n", (int)tp->tv_sec, (int)tp->tv_nsec); sdbg("Returning tp=(%d,%d)\n", (int)tp->tv_sec, (int)tp->tv_nsec);
} }
/* CLOCK_ACTIVETIME is non-standard. Returns active UTC time, which is
* disabled during power down modes. Unit is 1 second.
*/
#ifdef CONFIG_SYSTEM_UTC
else if (clock_id == CLOCK_ACTIVETIME && g_rtc_enabled && tp)
{
/* Disable interrupts while g_system_utc and g_tickcount are sampled
* so that we can be assured that g_system_utc and g_tickcount are based
* at the same point in time.
*/
flags = irqsave();
system_utc = g_system_utc;
tickcount = g_tickcount;
irqrestore(flags);
tp->tv_sec = system_utc;
tp->tv_nsec = tickcount * (1000000000/TICK_PER_SEC);
}
#endif
else else
{ {
sdbg("Returning ERROR\n"); sdbg("Returning ERROR\n");
+10 -74
View File
@@ -38,6 +38,7 @@
****************************************************************************/ ****************************************************************************/
#include <nuttx/config.h> #include <nuttx/config.h>
#include <nuttx/compiler.h>
#include <stdint.h> #include <stdint.h>
#include <time.h> #include <time.h>
@@ -53,27 +54,12 @@
/**************************************************************************** /****************************************************************************
* Definitions * Definitions
****************************************************************************/ ****************************************************************************/
#ifdef CONFIG_RTC
# ifndef CONFIG_SYSTEM_UTC
# error "In order to support hardware RTC system must have set the CONFIG_SYSTEM_UTC=y"
# endif
#endif
/* Standard time definitions (in units of seconds) */ /* Standard time definitions (in units of seconds) */
#define SEC_PER_MIN ((time_t)60) #define SEC_PER_MIN ((time_t)60)
#define SEC_PER_HOUR ((time_t)60 * SEC_PER_MIN) #define SEC_PER_HOUR ((time_t)60 * SEC_PER_MIN)
#define SEC_PER_DAY ((time_t)24 * SEC_PER_HOUR) #define SEC_PER_DAY ((time_t)24 * SEC_PER_HOUR)
/* Macro to increment the system timer -- or not */
#ifndef CONFIG_SYSTEM_UTC
# define incr_systimer() g_system_timer++
#else
# define incr_systimer()
#endif
/**************************************************************************** /****************************************************************************
* Private Type Declarations * Private Type Declarations
****************************************************************************/ ****************************************************************************/
@@ -90,59 +76,23 @@
* Public Variables * Public Variables
****************************************************************************/ ****************************************************************************/
#if CONFIG_SYSTEM_UTC #ifdef CONFIG_SYSTEM_TIME64
volatile time_t g_system_utc; volatile uint64_t g_system_timer;
uint64_t g_tickbias;
#else #else
volatile clock_t g_system_timer; volatile uint32_t g_system_timer;
struct timespec g_basetime; uint32_t g_tickbias;
uint32_t g_tickbias;
#endif #endif
struct timespec g_basetime;
/************************************************************************** /**************************************************************************
* Private Variables * Private Variables
**************************************************************************/ **************************************************************************/
/* This variable is used to count ticks and to increment the one-second
* UTC variable.
*/
#if CONFIG_SYSTEM_UTC
#if TICK_PER_SEC > 32767
volatile uint32_t g_tickcount;
#elif TICK_PER_SEC > 255
volatile uint16_t g_tickcount;
#else
volatile uint8_t g_tickcount;
#endif
#endif /* CONFIG_SYSTEM_UTC */
/************************************************************************** /**************************************************************************
* Private Functions * Private Functions
**************************************************************************/ **************************************************************************/
/****************************************************************************
* Function: incr_utc
*
* Description:
* This function must be called once every time the real
* time clock interrupt occurs. The interval of this
* clock interrupt must be MSEC_PER_TICK
*
****************************************************************************/
#if CONFIG_SYSTEM_UTC
static inline void incr_utc(void)
{
g_tickcount++;
if (g_tickcount >= TICK_PER_SEC)
{
g_system_utc++;
g_tickcount -= TICK_PER_SEC;
}
}
#else
# define incr_utc()
#endif
/**************************************************************************** /****************************************************************************
* Function: clock_inittime * Function: clock_inittime
@@ -210,27 +160,17 @@ static inline void clock_inittime(FAR struct timespec *tp)
void clock_initialize(void) void clock_initialize(void)
{ {
#ifdef CONFIG_SYSTEM_UTC
struct timespec ts;
#endif
/* Initialize the RTC hardware */ /* Initialize the RTC hardware */
#ifdef CONFIG_RTC #ifdef CONFIG_RTC
up_rtcinitialize(); up_rtcinitialize();
#endif #endif
/* Initialize the time value */ /* Initialize the time value to match */
#ifdef CONFIG_SYSTEM_UTC
clock_inittime(&ts);
g_system_utc = ts.tv_sec;
g_tickcount = ((ts.tv_nsec > 10) * CLOCKS_PER_SEC) / (1000000000 >> 10);
#else
clock_inittime(&g_basetime); clock_inittime(&g_basetime);
g_system_timer = 0; g_system_timer = 0;
g_tickbias = 0; g_tickbias = 0;
#endif
} }
/**************************************************************************** /****************************************************************************
@@ -247,9 +187,5 @@ void clock_timer(void)
{ {
/* Increment the per-tick system counter */ /* Increment the per-tick system counter */
incr_systimer(); g_system_timer++;
/* Increment the per-second UTC counter */
incr_utc();
} }
+16 -2
View File
@@ -43,12 +43,21 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#include <stdint.h> #include <stdint.h>
#include <nuttx/clock.h> #include <nuttx/clock.h>
#include <nuttx/compiler.h> #include <nuttx/compiler.h>
/******************************************************************************** /********************************************************************************
* Definitions * Pre-processor Definitions
********************************************************************************/ ********************************************************************************/
/* Configuration ************************************************************/
/* If CONFIG_SYSTEM_TIME64 is selected and the CPU supports long long types,
* then a 64-bit system time will be used.
*/
#ifndef CONFIG_HAVE_LONG_LONG
# undef CONFIG_SYSTEM_TIME64
#endif
/******************************************************************************** /********************************************************************************
* Public Type Definitions * Public Type Definitions
@@ -58,8 +67,13 @@
* Global Variables * Global Variables
********************************************************************************/ ********************************************************************************/
extern struct timespec g_basetime; #ifdef CONFIG_SYSTEM_TIME64
extern uint64_t g_tickbias;
#else
extern uint32_t g_tickbias; extern uint32_t g_tickbias;
#endif
extern struct timespec g_basetime;
/******************************************************************************** /********************************************************************************
* Public Function Prototypes * Public Function Prototypes
+13 -38
View File
@@ -89,17 +89,25 @@
int clock_settime(clockid_t clock_id, FAR const struct timespec *tp) int clock_settime(clockid_t clock_id, FAR const struct timespec *tp)
{ {
irqstate_t flags;
int ret = OK; int ret = OK;
sdbg("clock_id=%d\n", clock_id); sdbg("clock_id=%d\n", clock_id);
DEBUGASSERT(tp != NULL);
/* CLOCK_REALTIME - POSIX demands this to be present. This is the wall /* CLOCK_REALTIME - POSIX demands this to be present. This is the wall
* time clock. * time clock.
*/ */
if (clock_id == CLOCK_REALTIME && tp) if (clock_id == CLOCK_REALTIME)
{ {
#ifndef CONFIG_SYSTEM_UTC /* Interrupts are disabled here so that the in-memory time
* representation and the RTC setting will be as close as
* possible.
*/
flags = irqsave();
/* Save the new base time. */ /* Save the new base time. */
g_basetime.tv_sec = tp->tv_sec; g_basetime.tv_sec = tp->tv_sec;
@@ -109,55 +117,22 @@ int clock_settime(clockid_t clock_id, FAR const struct timespec *tp)
* as appropriate. * as appropriate.
*/ */
g_tickbias = clock_systimer(); g_tickbias = g_system_timer;
#else /* if CONFIG_SYSTEM_UTC=y */ /* Setup the RTC (lo- or high-res) */
/* We ignore everything below one second in time configuration */
#ifdef CONFIG_RTC #ifdef CONFIG_RTC
if (g_rtc_enabled) if (g_rtc_enabled)
{ {
up_rtc_settime(tp); up_rtc_settime(tp);
} }
else
#endif
{
g_system_utc = tp->tv_sec;
}
#endif #endif
irqrestore(flags);
sdbg("basetime=(%d,%d) tickbias=%d\n", sdbg("basetime=(%d,%d) tickbias=%d\n",
(int)g_basetime.tv_sec, (int)g_basetime.tv_nsec, (int)g_basetime.tv_sec, (int)g_basetime.tv_nsec,
(int)g_tickbias); (int)g_tickbias);
} }
/* CLOCK_ACTIVETIME is non-standard. Returns active UTC time, which is
* disabled during power down modes. Unit is 1 second.
*/
#ifdef CONFIG_SYSTEM_UTC
else if (clock_id == CLOCK_ACTIVETIME && tp)
{
irqstate_t flags;
uint32_t tickcount;
/* Calculate the number of ticks correspond to the nanosecond count...
* exercising care to avoid overflows. This could still overflow
* if CLOCKS_PER_SEC is very large (something like 4096).
*/
tickcount = ((tp->tv_nsec >> 10) * CLOCKS_PER_SEC) / (1000000000 >> 10);
/* Then set the UTC time (seconds) plus the tickcount (fractional seconds */
flags = irqsave();
g_system_utc = tp->tv_sec;
g_tickcount = tickcount;
irqrestore(flags);
}
#endif
else else
{ {
sdbg("Returning ERROR\n"); sdbg("Returning ERROR\n");
+30 -34
View File
@@ -42,12 +42,8 @@
#include <stdint.h> #include <stdint.h>
#include <nuttx/clock.h> #include <nuttx/clock.h>
#include <nuttx/rtc.h>
#include <nuttx/time.h>
#include <arch/irq.h> #include "clock_internal.h"
#if !defined(clock_systimer) /* See nuttx/clock.h */
/**************************************************************************** /****************************************************************************
* Pre-processor Definitions * Pre-processor Definitions
@@ -65,7 +61,7 @@
* Function: clock_systimer * Function: clock_systimer
* *
* Description: * Description:
* Return the current value of the system timer counter * Return the current value of the 32-bit system timer counter
* *
* Parameters: * Parameters:
* None * None
@@ -77,38 +73,38 @@
* *
****************************************************************************/ ****************************************************************************/
#if !defined(clock_systimer) /* See nuttx/clock.h */
uint32_t clock_systimer(void) uint32_t clock_systimer(void)
{ {
#ifdef CONFIG_SYSTEM_UTC #ifdef CONFIG_SYSTEM_TIME64
irqstate_t flags; return (uint32_t)(g_system_timer & 0x00000000ffffffff);
uint32_t system_utc;
uint32_t tickcount;
#endif
#ifdef CONFIG_RTC_HIRES
/* Fetch the g_system_timer value from timer hardware, if available.
*
* Note that the unit of the g_system_timer and and up_rtc_gettime() do
* not have the same unit.
*/
#endif
#ifndef CONFIG_SYSTEM_UTC
return g_system_timer;
#else #else
/* Disable interrupts while g_system_utc and g_tickcount are sampled return g_system_timer;
* so that we can be assured that g_system_utc and g_tickcount are based
* at the same point in time.
*/
flags = irqsave();
system_utc = g_system_utc;
tickcount = g_tickcount;
irqrestore(flags);
return system_utc * TICK_PER_SEC + tickcount;
#endif #endif
} }
#endif
#endif /* !clock_systtimer */ /****************************************************************************
* Function: clock_systimer64
*
* Description:
* Return the current value of the 64-bit system timer counter
*
* Parameters:
* None
*
* Return Value:
* The current value of the system timer counter
*
* Assumptions:
*
****************************************************************************/
#if !defined(clock_systimer) /* See nuttx/clock.h */
#ifdef CONFIG_SYSTEM_TIME64
uint64_t clock_systimer64(void)
{
return g_system_timer;
}
#endif
#endif