diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2011-05-06 21:10:00 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2011-05-06 21:10:00 +0000 |
commit | bbbdceb9d13441f4b96257718ed090b8998759f7 (patch) | |
tree | 6bb4e7cbc0c05dc47f8d7de2848b67b189bd5279 | |
parent | 4c3a7673e9a391302a0e2417d8846bfdf7d9171f (diff) | |
download | px4-nuttx-bbbdceb9d13441f4b96257718ed090b8998759f7.tar.gz px4-nuttx-bbbdceb9d13441f4b96257718ed090b8998759f7.tar.bz2 px4-nuttx-bbbdceb9d13441f4b96257718ed090b8998759f7.zip |
More timer changes from Uros
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3572 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r-- | nuttx/ChangeLog | 4 | ||||
-rw-r--r-- | nuttx/Documentation/NuttxPortingGuide.html | 87 | ||||
-rw-r--r-- | nuttx/configs/vsn/src/sif.c | 15 | ||||
-rw-r--r-- | nuttx/include/nuttx/clock.h | 36 | ||||
-rw-r--r-- | nuttx/include/time.h | 25 | ||||
-rw-r--r-- | nuttx/sched/Makefile | 4 | ||||
-rw-r--r-- | nuttx/sched/clock_gettime.c | 51 | ||||
-rw-r--r-- | nuttx/sched/clock_getutc.c | 92 | ||||
-rw-r--r-- | nuttx/sched/clock_initialize.c | 45 | ||||
-rw-r--r-- | nuttx/sched/clock_settime.c | 49 | ||||
-rw-r--r-- | nuttx/sched/clock_systimer.c | 10 |
11 files changed, 244 insertions, 174 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog index a3547a2ac..e9174fb53 100644 --- a/nuttx/ChangeLog +++ b/nuttx/ChangeLog @@ -1725,3 +1725,7 @@ 6.3 2011-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr> + * Remove clock_getutc(). It is replaces with clock_gettime(CLOCK_ACTIVETIME). + Add other RTC related changes provided by Uros Platise. + + diff --git a/nuttx/Documentation/NuttxPortingGuide.html b/nuttx/Documentation/NuttxPortingGuide.html index 4f9b0694f..c7a56927f 100644 --- a/nuttx/Documentation/NuttxPortingGuide.html +++ b/nuttx/Documentation/NuttxPortingGuide.html @@ -91,7 +91,8 @@ <a href="#updisableirq">4.1.16 <code>up_disable_irq()</code></a><br> <a href="#upenableirq">4.1.17 <code>up_enable_irq()</code></a><br> <a href="#upprioritizeirq">4.1.18 <code>up_prioritize_irq()</code></a></br> - <a href="#upputc">4.1.19 <code>up_putc()</code></a> + <a href="#upputc">4.1.19 <code>up_putc()</code></a></br> + <a href="#systemtime">4.1.20 System Time and Clock</a> </ul> <a href="#exports">4.2 APIs Exported by NuttX to Architecture-Specific Logic</a> <ul> @@ -1642,6 +1643,90 @@ The system can be re-made subsequently by just typing <code>make</code>. Output one character on the console </p> +<h3><a name="systemtime">4.1.20 System Time and Clock</a></h3> + +<h4>4.1.20.1 UTC Time Representation</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> + To enable hardware module use option: +<p> +<ul><pre> +CONFIG_RTC=y +</pre></ul> +<p> + which requires the following three base functions to read time: +</p> +<ul> + <li><code>up_rtcinitialize()</code></li> + <li><code>up_rtc_gettime()</code>. UTC time in seconds.</li> + <li><code>up_rtc_getclock()</code>. Replacement for <code>g_system_tick</code></li> +</ul> +<p> + This module depends on <code>CONFIG_SYSTEM_UTC=y</code>. +</p> + +<h4>4.1.20.3 System Tick and Time</h4> +<p> + The system tick is represented by, when <code>CONFIG_SYSTEM_UTC=n</code>: +</p> +<ul> + <li><code>g_system_timer</code></li> +</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> + Running at rate of system base timer, used for time-slicing, and so forth. +</p> +<p> + If hardware RTC is present (<code>CONFIG_RTC</code>) and enabled, then after successful + initiliazation variables are overriden by calls to <code>up_rtc_getclock()</code> which is + running continously even in power-down modes. +</p> +<p> + In the case of <code>CONFIG_RTC</code> is set the <code>g_tickcount</code> and <code>g_system_utc</code> keep + counting at rate of a system timer, which however, is disabled in power-down + mode. By comparing this time and RTC (actual time) one may determine the + actual system active time. To retrieve that variable use: +</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> <p> These are standard interfaces that are exported by the OS diff --git a/nuttx/configs/vsn/src/sif.c b/nuttx/configs/vsn/src/sif.c index 2d5351e87..4be214444 100644 --- a/nuttx/configs/vsn/src/sif.c +++ b/nuttx/configs/vsn/src/sif.c @@ -508,8 +508,9 @@ int sif_main(int argc, char *argv[]) return 0; } else if (!strcmp(argv[1], "time") && argc == 3) { - int val = atoi(argv[2]); - up_rtc_settime(val); + struct timespec t_set; + t_set.tv_sec = atoi(argv[2]); + clock_settime(CLOCK_REALTIME, &t_set); } else if (!strcmp(argv[1], "i2c") && argc == 3) { int val = atoi(argv[2]); @@ -551,7 +552,13 @@ int sif_main(int argc, char *argv[]) } fprintf(stderr, "%s:\tinit\n\tgpio\tA B\n\tpwr\tval\n", argv[0]); - fprintf(stderr, "time = %d / %d, time = %d\n", - up_rtc_gettime(), up_rtc_getclock(), time(NULL) ); + + struct timespec t_active; + clock_gettime(CLOCK_ACTIVETIME, &t_active); + + fprintf(stderr, "rtc time = %u / %u, active = %u / %u, time / systick = %u / %u\n", + up_rtc_gettime(), up_rtc_getclock(), + t_active.tv_sec, t_active.tv_nsec, + time(NULL), clock_systimer() ); return -1; } diff --git a/nuttx/include/nuttx/clock.h b/nuttx/include/nuttx/clock.h index cde1dd2db..71f0c7e8a 100644 --- a/nuttx/include/nuttx/clock.h +++ b/nuttx/include/nuttx/clock.h @@ -128,15 +128,18 @@ #if __HAVE_KERNEL_GLOBALS extern volatile uint32_t g_system_timer; extern volatile uint32_t g_system_utc; -#endif - -#if !defined(CONFIG_RTC) && __HAVE_KERNEL_GLOBALS -#define clock_systimer() g_system_timer -#if defined(CONFIG_SYSTEM_UTC) -#define clock_getutc() 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 #endif /**************************************************************************** @@ -173,27 +176,6 @@ extern "C" { EXTERN uint32_t clock_systimer(void); #endif -/**************************************************************************** - * Function: clock_getutc - * - * Description: - * Return the current value of the system timer counter, which is only - * enabled when system is in active mode. - * - * Parameters: - * None - * - * Return Value: - * The current value of the system time counter - * - * Assumptions: - * - ****************************************************************************/ - -#if defined(CONFIG_SYSTEM_UTC) && !__HAVE_KERNEL_GLOBALS -EXTERN time_t clock_getutc(void); -#endif - #undef EXTERN #ifdef __cplusplus } diff --git a/nuttx/include/time.h b/nuttx/include/time.h index fab20e020..c52e74bf2 100644 --- a/nuttx/include/time.h +++ b/nuttx/include/time.h @@ -60,28 +60,37 @@ */ #ifdef CONFIG_MSEC_PER_TICK -# define CLK_TCK (1000/CONFIG_MSEC_PER_TICK) -# define CLOCKS_PER_SEC (1000/CONFIG_MSEC_PER_TICK) +# define CLK_TCK (1000/CONFIG_MSEC_PER_TICK) +# define CLOCKS_PER_SEC (1000/CONFIG_MSEC_PER_TICK) #else -# define CLK_TCK (100) -# define CLOCKS_PER_SEC (100) +# define CLK_TCK (100) +# define CLOCKS_PER_SEC (100) #endif /* This is the only clock_id supported by the "Clock and Timer * Functions." */ -#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_RTC +# define CLOCK_ACTIVETIME 1 +#endif + #define CLOCK_ABSTIME /* This is a flag that may be passed to the timer_settime() function */ -#define TIMER_ABSTIME 1 +#define TIMER_ABSTIME 1 /* Local time is the same as gmtime in this implementation */ -#define localtime(c) gmtime(c) -#define localtime_r(c,r) gmtime_r(c,r) +#define localtime(c) gmtime(c) +#define localtime_r(c,r) gmtime_r(c,r) /******************************************************************************** * Global Type Declarations diff --git a/nuttx/sched/Makefile b/nuttx/sched/Makefile index 2ad17f826..859bd57b4 100644 --- a/nuttx/sched/Makefile +++ b/nuttx/sched/Makefile @@ -80,10 +80,6 @@ CLOCK_SRCS = clock_initialize.c clock_settime.c clock_gettime.c clock_getres.c \ clock_time2ticks.c clock_abstime2ticks.c clock_ticks2time.c \ clock_gettimeofday.c clock_systimer.c -ifeq ($(CONFIG_SYSTEM_UTC),y) -CLOCK_SRCS += clock_getutc.c -endif - SIGNAL_SRCS = sig_initialize.c \ sig_action.c sig_procmask.c sig_pending.c sig_suspend.c \ sig_kill.c sig_queue.c sig_waitinfo.c sig_timedwait.c \ diff --git a/nuttx/sched/clock_gettime.c b/nuttx/sched/clock_gettime.c index f3ffe2a6c..59e5b604c 100644 --- a/nuttx/sched/clock_gettime.c +++ b/nuttx/sched/clock_gettime.c @@ -38,6 +38,7 @@ ************************************************************************/ #include <nuttx/config.h> +#include <nuttx/rtc.h> #include <stdint.h> #include <time.h> @@ -95,17 +96,13 @@ int clock_gettime(clockid_t clock_id, struct timespec *tp) sdbg("clock_id=%d\n", clock_id); - /* Only CLOCK_REALTIME is supported */ + /* CLOCK_REALTIME - POSIX demands this to be present. This is the wall + * time clock. + */ - if (clock_id != CLOCK_REALTIME) - { - sdbg("Returning ERROR\n"); - - *get_errno_ptr() = EINVAL; - ret = ERROR; - } - else + if (clock_id == CLOCK_REALTIME && tp) { +#ifndef CONFIG_SYSTEM_UTC /* Get the elapsed time since power up (in milliseconds) biased * as appropriate. */ @@ -142,10 +139,46 @@ int clock_gettime(clockid_t clock_id, struct timespec *tp) tp->tv_sec = (time_t)secs; tp->tv_nsec = (long)nsecs; + +#else /* if CONFIG_SYSTEM_UTC=y */ + +#ifdef CONFIG_RTC + if (g_rtc_enabled) + { + tp->tv_sec = up_rtc_gettime(); + tp->tv_nsec = (up_rtc_getclock() & (RTC_CLOCKS_PER_SEC-1) ) * (1000000000/TICK_PER_SEC); + } + else +#endif + { + tp->tv_sec = g_system_utc; + tp->tv_nsec = g_tickcount * (1000000000/TICK_PER_SEC); + } +#endif 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_RTC + else if (clock_id == CLOCK_ACTIVETIME && g_rtc_enabled && tp) + { + tp->tv_sec = g_system_utc; + tp->tv_nsec = g_tickcount * (1000000000/TICK_PER_SEC); + } +#endif + + else + { + sdbg("Returning ERROR\n"); + + errno = EINVAL; + ret = ERROR; + } + return ret; } diff --git a/nuttx/sched/clock_getutc.c b/nuttx/sched/clock_getutc.c deleted file mode 100644 index 95c097019..000000000 --- a/nuttx/sched/clock_getutc.c +++ /dev/null @@ -1,92 +0,0 @@ -/**************************************************************************** - * sched/clock_getutc.c - * - * Copyright (C) 2011 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt <spudmonkey@racsa.co.cr> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include <nuttx/config.h> - -#include <stdint.h> -#include <nuttx/clock.h> -#include <nuttx/time.h> -#include <nuttx/rtc.h> - -#if !defined(CONFIG_DISABLE_CLOCK) && defined(CONFIG_SYSTEM_UTC) && !defined(clock_getutc) - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Function: clock_getutc - * - * Description: - * Return the current value of the system timer counter, which is only - * enabled when system is in active mode. - * - * Parameters: - * None - * - * Return Value: - * The current value of the system time counter - * - * Assumptions: - * - ****************************************************************************/ - -time_t clock_getutc(void) -{ -#ifdef CONFIG_RTC - if (g_rtc_enabled) - { - return up_rtc_gettime(); - } - else -#endif - { - return g_system_utc; - } -} - -#endif /* CONFIG_DISABLE_CLOCK && CONFIG_SYSTEM_UTC */ diff --git a/nuttx/sched/clock_initialize.c b/nuttx/sched/clock_initialize.c index 91220c19e..8919b6005 100644 --- a/nuttx/sched/clock_initialize.c +++ b/nuttx/sched/clock_initialize.c @@ -60,9 +60,13 @@ #define SEC_PER_HOUR ((time_t)60 * SEC_PER_MIN) #define SEC_PER_DAY ((time_t)24 * SEC_PER_HOUR) -/* Defined just so the UTC counter and system counter/timer look similar */ +/* Macro to increment the system timer -- or not */ -#define incr_systimer() g_system_timer++ +#ifndef CONFIG_SYSTEM_UTC +# define incr_systimer() g_system_timer++ +#else +# define incr_systimer() +#endif /**************************************************************************** * Private Type Declarations @@ -80,14 +84,13 @@ * Public Variables ****************************************************************************/ -volatile clock_t g_system_timer = 0; - #if CONFIG_SYSTEM_UTC volatile time_t g_system_utc = 0; -#endif - +#else +volatile clock_t g_system_timer = 0; struct timespec g_basetime = {0,0}; uint32_t g_tickbias = 0; +#endif /************************************************************************** * Private Variables @@ -99,11 +102,11 @@ uint32_t g_tickbias = 0; #if CONFIG_SYSTEM_UTC #if TICK_PER_SEC > 32767 -static uint32_t g_tickcount = 0; +volatile uint32_t g_tickcount = 0; #elif TICK_PER_SEC > 255 -static uint16_t g_tickcount = 0; +volatile uint16_t g_tickcount = 0; #else -static uint8_t g_tickcount = 0; +volatile uint8_t g_tickcount = 0; #endif #endif /* CONFIG_SYSTEM_UTC */ @@ -153,32 +156,39 @@ static inline void incr_utc(void) void clock_initialize(void) { +#ifndef CONFIG_SYSTEM_UTC time_t jdn = 0; +#endif /* Initialize the real time close (this should be un-nesssary except on a * restart). */ - g_system_timer = 0; #ifdef CONFIG_SYSTEM_UTC g_system_utc = 0; +#else + g_system_timer = 0; #endif - /* Do we have hardware periodic timer support? */ + /* Do we have hardware RTC support? */ #ifdef CONFIG_RTC + +#ifndef CONFIG_SYSTEM_UTC +# error In order to support hardware RTC system must have set the CONFIG_SYSTEM_UTC=y +#endif + up_rtcinitialize(); +#endif + +#ifndef CONFIG_SYSTEM_UTC /* Get the EPOCH-relative julian date from the calendar year, * month, and date */ - if (g_rtc_enabled==false) -#endif - { - jdn = clock_calendar2utc(CONFIG_START_YEAR, CONFIG_START_MONTH, - CONFIG_START_DAY); - } + jdn = clock_calendar2utc(CONFIG_START_YEAR, CONFIG_START_MONTH, + CONFIG_START_DAY); /* Set the base time as seconds into this julian day. */ @@ -188,6 +198,7 @@ void clock_initialize(void) /* These is no time bias from this time. */ g_tickbias = 0; +#endif } /**************************************************************************** diff --git a/nuttx/sched/clock_settime.c b/nuttx/sched/clock_settime.c index 2af27acf1..72fb8276e 100644 --- a/nuttx/sched/clock_settime.c +++ b/nuttx/sched/clock_settime.c @@ -38,6 +38,7 @@ ************************************************************************/ #include <nuttx/config.h> +#include <nuttx/rtc.h> #include <time.h> #include <errno.h> @@ -90,16 +91,13 @@ int clock_settime(clockid_t clock_id, const struct timespec *tp) sdbg("clock_id=%d\n", clock_id); - /* Only CLOCK_REALTIME is supported */ + /* CLOCK_REALTIME - POSIX demands this to be present. This is the wall + * time clock. + */ - if (clock_id != CLOCK_REALTIME || !tp) - { - sdbg("Returning ERROR\n"); - *get_errno_ptr() = EINVAL; - ret = ERROR; - } - else + if (clock_id == CLOCK_REALTIME && tp) { +#ifndef CONFIG_SYSTEM_UTC /* Save the new base time. */ g_basetime.tv_sec = tp->tv_sec; @@ -110,11 +108,44 @@ int clock_settime(clockid_t clock_id, const struct timespec *tp) */ g_tickbias = clock_systimer(); + +#else /* if CONFIG_SYSTEM_UTC=y */ + + /* We ignore everything below one second in time configuration */ + +#ifdef CONFIG_RTC + if (g_rtc_enabled) + { + up_rtc_settime( tp->tv_sec ); + } + else +#endif + g_system_utc = tp->tv_sec; + +#endif sdbg("basetime=(%d,%d) tickbias=%d\n", (int)g_basetime.tv_sec, (int)g_basetime.tv_nsec, (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_RTC + else if (clock_id == CLOCK_ACTIVETIME && g_rtc_enabled && tp) + { + g_system_utc = tp->tv_sec; + } +#endif + + else + { + sdbg("Returning ERROR\n"); + *get_errno_ptr() = EINVAL; + ret = ERROR; + } return ret; } diff --git a/nuttx/sched/clock_systimer.c b/nuttx/sched/clock_systimer.c index c4560a8a1..a1219a681 100644 --- a/nuttx/sched/clock_systimer.c +++ b/nuttx/sched/clock_systimer.c @@ -83,17 +83,21 @@ uint32_t clock_systimer(void) /* Check if the periodic timer is initialized * - * Note that the unit of the g_system_timer and and up_rtc_getclock() must - * be the same in order (must have same [unit]) to allow smooth transitions. + * Note that the unit of the g_system_timer and and up_rtc_getclock() do + * not have the same unit. */ if (g_rtc_enabled) { -// return up_rtc_getclock(); + return up_rtc_getclock(); } #endif +#ifndef CONFIG_SYSTEM_UTC return g_system_timer; +#else + return g_system_utc * TICK_PER_SEC + g_tickcount; +#endif } #endif /* !clock_systtimer */ |