2007-04-02 Joel Sherrill <joel@OARcorp.com>

* itron/src/itrontime.c, libcsupport/src/__gettod.c,
	posix/include/rtems/posix/time.h, posix/include/rtems/posix/timer.h,
	posix/src/clockgettime.c, posix/src/clocksettime.c,
	posix/src/nanosleep.c, posix/src/posixtimespecsubtract.c,
	posix/src/posixtimespectointerval.c, posix/src/ptimer1.c,
	posix/src/sleep.c, rtems/Makefile.am,
	rtems/include/rtems/rtems/clock.h, rtems/include/rtems/rtems/timer.h,
	rtems/include/rtems/rtems/types.h, rtems/src/clockget.c,
	rtems/src/clockset.c, rtems/src/clocktodtoseconds.c,
	rtems/src/clocktodvalidate.c, rtems/src/taskwakewhen.c,
	score/Makefile.am, score/include/rtems/score/tod.h,
	score/inline/rtems/score/tod.inl, score/src/coretod.c,
	score/src/coretodset.c: Convert from Classic API style TOD_Control as
	fundamental time structure to POSIX struct timespec. Add
	clock_get_uptime().
	* rtems/src/clockgetuptime.c, score/src/coretodget.c,
	score/src/coretodgetuptime.c: New files.
	* score/src/coretodtickle.c, score/src/coretodtoseconds.c,
	score/src/coretodvalidate.c: Removed.
This commit is contained in:
Joel Sherrill
2007-04-02 18:23:59 +00:00
parent bf4d016650
commit 812da54688
32 changed files with 497 additions and 540 deletions
+22
View File
@@ -1,3 +1,25 @@
2007-04-02 Joel Sherrill <joel@OARcorp.com>
* itron/src/itrontime.c, libcsupport/src/__gettod.c,
posix/include/rtems/posix/time.h, posix/include/rtems/posix/timer.h,
posix/src/clockgettime.c, posix/src/clocksettime.c,
posix/src/nanosleep.c, posix/src/posixtimespecsubtract.c,
posix/src/posixtimespectointerval.c, posix/src/ptimer1.c,
posix/src/sleep.c, rtems/Makefile.am,
rtems/include/rtems/rtems/clock.h, rtems/include/rtems/rtems/timer.h,
rtems/include/rtems/rtems/types.h, rtems/src/clockget.c,
rtems/src/clockset.c, rtems/src/clocktodtoseconds.c,
rtems/src/clocktodvalidate.c, rtems/src/taskwakewhen.c,
score/Makefile.am, score/include/rtems/score/tod.h,
score/inline/rtems/score/tod.inl, score/src/coretod.c,
score/src/coretodset.c: Convert from Classic API style TOD_Control as
fundamental time structure to POSIX struct timespec. Add
clock_get_uptime().
* rtems/src/clockgetuptime.c, score/src/coretodget.c,
score/src/coretodgetuptime.c: New files.
* score/src/coretodtickle.c, score/src/coretodtoseconds.c,
score/src/coretodvalidate.c: Removed.
2007-04-02 Joel Sherrill <joel@OARcorp.com>
* libcsupport/src/printk.c: Add %p support.
+5 -24
View File
@@ -20,24 +20,6 @@
#include <rtems/itron/time.h>
/*
* set_tim - Set System Clock
*/
void converTime(SYSTIME ms, TOD_Control *time)
{
int millisecond;
/* XXX need to dereference structure */
#if 0
milisecond = ms % 1000;
tempSecond = ms / 1000;
#else
millisecond = 0;
#endif
}
/*
* set_tim - Set System Clock
*/
@@ -46,8 +28,8 @@ ER set_tim(
SYSTIME *pk_tim
)
{
Watchdog_Interval temp; /* an integer in seconds after conversion from SYSTIME */
TOD_Control the_tod;
#if 0
struct timespec time;
/* convert *pk_tim which is 48 bits integer in binary into an ordinary
integer in milliseconds */
@@ -55,12 +37,11 @@ ER set_tim(
/* XXX */ temp = 0;
if(temp > 0) {
_Thread_Disable_dispatch();
_TOD_Set(&the_tod, temp);
_TOD_Set(&the_tod);
_Thread_Enable_dispatch();
if(_TOD_Validate(&the_tod)){
return E_OK;
}
return E_OK;
}
#endif
return E_SYS;
}
+1 -23
View File
@@ -28,16 +28,6 @@
#include <time.h>
#include <errno.h>
#include <assert.h>
/*
* Seconds from January 1, 1970 to January 1, 1988. Used to account for
* differences between POSIX API and RTEMS core.
*/
#define POSIX_TIME_SECONDS_1970_THROUGH_1988 \
(((1987 - 1970 + 1) * TOD_SECONDS_PER_NON_LEAP_YEAR) + \
(4 * TOD_SECONDS_PER_DAY))
/*
* NOTE: The solaris gettimeofday does not have a second parameter.
@@ -48,10 +38,6 @@ int gettimeofday(
struct timezone *tzp
)
{
rtems_interrupt_level level;
uint32_t seconds;
uint32_t microseconds;
if ( !tp ) {
errno = EFAULT;
return -1;
@@ -60,17 +46,9 @@ int gettimeofday(
/*
* POSIX does not seem to allow for not having a TOD so we just
* grab the time of day.
*
* NOTE: XXX this routine should really be in the executive proper.
*/
rtems_interrupt_disable(level);
seconds = _TOD_Seconds_since_epoch;
microseconds = _TOD_Current.ticks;
rtems_interrupt_enable(level);
tp->tv_sec = seconds + POSIX_TIME_SECONDS_1970_THROUGH_1988;
tp->tv_usec = microseconds * _TOD_Microseconds_per_tick;
_TOD_Get_timeval( tp );
/*
* Timezone information ignored by the OS proper. Per email
+4 -4
View File
@@ -16,11 +16,11 @@
/*
* Seconds from January 1, 1970 to January 1, 1988. Used to account for
* differences between POSIX API and RTEMS core.
*
* XXX probably able to be removed once core switches completely to timespec
* XXX for current TOD.
*/
#define POSIX_TIME_SECONDS_1970_THROUGH_1988 \
(((1987 - 1970 + 1) * TOD_SECONDS_PER_NON_LEAP_YEAR) + \
(4 * TOD_SECONDS_PER_DAY))
#define POSIX_TIME_SECONDS_1970_THROUGH_1988 TOD_SECONDS_1970_THROUGH_1988
/*
* _POSIX_Timespec_subtract
+1 -1
View File
@@ -47,7 +47,7 @@ typedef struct {
struct itimerspec timer_data; /* Timing data of the timer */
uint32_t ticks; /* Number of ticks of the initialization */
uint32_t overrun; /* Number of expirations of the timer */
TOD_Control time; /* Time in which the timer was started */
struct timespec time; /* Time in which the timer was started */
} POSIX_Timer_Control;
/*
+8 -15
View File
@@ -27,31 +27,24 @@ int clock_gettime(
struct timespec *tp
)
{
ISR_Level level;
time_t seconds;
long ticks;
if ( !tp )
rtems_set_errno_and_return_minus_one( EINVAL );
switch ( clock_id ) {
case CLOCK_REALTIME:
_ISR_Disable( level );
seconds = _TOD_Seconds_since_epoch;
ticks = _TOD_Current.ticks;
_ISR_Enable( level );
tp->tv_sec = seconds + POSIX_TIME_SECONDS_1970_THROUGH_1988;
tp->tv_nsec = ticks * _TOD_Microseconds_per_tick *
TOD_NANOSECONDS_PER_MICROSECOND;
_TOD_Get(tp);
break;
#if 0
case CLOCK_MONOTONIC:
_TOD_Get_uptime(tp);
break;
#endif
#ifdef _POSIX_CPUTIME
case CLOCK_PROCESS_CPUTIME:
/* don't base this on _Watchdog_Ticks_since_boot--duration is too short*/
return POSIX_NOT_IMPLEMENTED();
_TOD_Get_uptime(tp);
break;
#endif
+4 -32
View File
@@ -6,7 +6,6 @@
#include "config.h"
#endif
#include <assert.h>
#include <time.h>
#include <errno.h>
@@ -28,44 +27,17 @@ int clock_settime(
const struct timespec *tp
)
{
struct tm split_time;
TOD_Control tod;
Watchdog_Interval seconds;
assert( tp );
if ( !tp )
rtems_set_errno_and_return_minus_one( EINVAL );
switch ( clock_id ) {
case CLOCK_REALTIME:
(void) gmtime_r( &tp->tv_sec, &split_time );
/*
* Convert the tm structure format to that used by the TOD Handler
*
* NOTE: TOD Handler does not honor leap seconds.
*/
tod.year = split_time.tm_year + 1900; /* RHS is years since 1900 */
tod.month = split_time.tm_mon + 1; /* RHS uses 0-11 */
tod.day = split_time.tm_mday;
tod.hour = split_time.tm_hour;
tod.minute = split_time.tm_min;
tod.second = split_time.tm_sec; /* RHS allows 0-61 for leap seconds */
tod.ticks = (tp->tv_nsec / TOD_NANOSECONDS_PER_MICROSECOND) /
_TOD_Microseconds_per_tick;
if ( !_TOD_Validate( &tod ) )
if ( tp->tv_sec < TOD_SECONDS_1970_THROUGH_1988 )
rtems_set_errno_and_return_minus_one( EINVAL );
/*
* We can't use the tp->tv_sec field because it is based on
* a different EPOCH.
*/
seconds = _TOD_To_seconds( &tod );
_Thread_Disable_dispatch();
_TOD_Set( &tod, seconds );
_TOD_Set( tp );
_Thread_Enable_dispatch();
break;
+10
View File
@@ -54,6 +54,13 @@ int nanosleep(
ticks = _POSIX_Timespec_to_interval( the_rqtp );
/*
* Bump the ticks by one so the delay is at least the number of
* ticks requested
*/
ticks++;
/*
* A nanosleep for zero time is implemented as a yield.
* This behavior is also beyond the POSIX specification but is
* consistent with the RTEMS api and yields desirable behavior.
*/
@@ -69,6 +76,9 @@ int nanosleep(
return 0;
}
/*
* Block for the desired amount of time
*/
_Thread_Disable_dispatch();
_Thread_Set_state(
_Thread_Executing,
+12 -3
View File
@@ -23,11 +23,12 @@
*/
void _POSIX_Timespec_subtract(
const struct timespec *the_start,
const struct timespec *start,
const struct timespec *end,
struct timespec *result
)
{
#if 0
struct timespec start_struct = *the_start;
struct timespec *start = &start_struct;
uint32_t nsecs_per_sec = TOD_NANOSECONDS_PER_SECOND;
@@ -43,7 +44,15 @@ void _POSIX_Timespec_subtract(
start->tv_nsec += nsecs_per_sec * seconds;
start->tv_sec -= seconds;
}
#else
result->tv_sec = end->tv_sec - start->tv_sec;
result->tv_nsec = end->tv_nsec - start->tv_nsec;
#endif
if (end->tv_nsec < start->tv_nsec) {
result->tv_sec = end->tv_sec - start->tv_sec - 1;
result->tv_nsec = (TOD_NANOSECONDS_PER_SECOND - start->tv_nsec) + end->tv_nsec;
} else {
result->tv_sec = end->tv_sec - start->tv_sec;
result->tv_nsec = end->tv_nsec - start->tv_nsec;
}
}
+1 -3
View File
@@ -28,9 +28,7 @@ Watchdog_Interval _POSIX_Timespec_to_interval(
{
Watchdog_Interval ticks;
ticks = (time->tv_sec * TOD_MICROSECONDS_PER_SECOND) /
_TOD_Microseconds_per_tick;
ticks = (time->tv_sec * _TOD_Ticks_per_second);
ticks += (time->tv_nsec / TOD_NANOSECONDS_PER_MICROSECOND) /
_TOD_Microseconds_per_tick;
+6 -47
View File
@@ -143,7 +143,7 @@ void _POSIX_Timer_TSR(Objects_Id timer, void *data)
return;
/* Store the time when the timer was started again */
ptimer->time = _TOD_Current;
_TOD_Get( &ptimer->time );
/* The state really did not change but just to be safe */
ptimer->state = STATE_CREATE_RUN_C;
@@ -383,7 +383,7 @@ int timer_settime(
ptimer->state = STATE_CREATE_RUN_C;
/* Stores the time in which the timer was started again */
ptimer->time = _TOD_Current;
_TOD_Get( &ptimer->time );
_Thread_Enable_dispatch();
return 0;
break;
@@ -416,7 +416,7 @@ int timer_settime(
/* Indicate that the time is running */
ptimer->state = STATE_CREATE_RUN_C;
ptimer->time = _TOD_Current;
_TOD_Get( &ptimer->time );
_Thread_Enable_dispatch();
return 0;
}
@@ -454,15 +454,10 @@ int timer_gettime(
POSIX_Timer_Control *ptimer;
Objects_Locations location;
rtems_time_of_day current_time;
uint32_t hours;
uint32_t minutes;
uint32_t seconds;
uint32_t ticks;
uint32_t nanosec;
struct timespec current_time;
/* Reads the current time */
current_time = _TOD_Current;
_TOD_Get( &current_time );
ptimer = _POSIX_Timer_Get( timerid, &location );
switch ( location ) {
@@ -476,46 +471,10 @@ int timer_gettime(
rtems_set_errno_and_return_minus_one( EINVAL );
case OBJECTS_LOCAL:
/* Calculates the difference between the start time of the timer and
* the current one */
hours = current_time.hour - ptimer->time.hour;
if ( current_time.minute < ptimer->time.minute ) {
minutes = 60 - ptimer->time.minute + current_time.minute;
hours--;
} else {
minutes = current_time.minute - ptimer->time.minute;
}
if ( current_time.second < ptimer->time.second ) {
seconds = 60 - ptimer->time.second + current_time.second;
minutes--;
} else {
seconds = current_time.second - ptimer->time.second;
}
if ( current_time.ticks < ptimer->time.ticks ) {
ticks = 100 - ptimer->time.ticks + current_time.ticks;
seconds--;
} else {
ticks = current_time.ticks - ptimer->time.ticks;
}
/* The time that the timer is running is calculated */
seconds = hours * 60 * 60 +
minutes * 60 +
seconds;
nanosec = ticks * 10 * /* msec */
1000 * /* microsec */
1000; /* nanosec */
/* Calculates the time left before the timer finishes */
value->it_value.tv_sec = ptimer->timer_data.it_value.tv_sec - seconds;
value->it_value.tv_nsec = ptimer->timer_data.it_value.tv_nsec - nanosec;
_POSIX_Timespec_subtract(&ptimer->timer_data.it_value, &current_time, &value->it_value);
value->it_interval.tv_sec = ptimer->timer_data.it_interval.tv_sec;
value->it_interval.tv_nsec = ptimer->timer_data.it_interval.tv_nsec;
-1
View File
@@ -18,7 +18,6 @@ unsigned int sleep(
unsigned int seconds
)
{
/* XXX can we get away with this implementation? */
struct timespec tp;
struct timespec tm;
+2 -1
View File
@@ -77,7 +77,8 @@ librtems_a_SOURCES += src/barrier.c src/barriercreate.c src/barrierdelete.c \
## CLOCK_C_FILES
librtems_a_SOURCES += src/rtclock.c src/clockget.c src/clockset.c \
src/clocktick.c src/clocksetnsecshandler.c
src/clocktick.c src/clocksetnsecshandler.c src/clockgetuptime.c \
src/clocktodtoseconds.c src/clocktodvalidate.c
## TIMER_C_FILES
librtems_a_SOURCES += src/rtemstimer.c src/timercancel.c src/timercreate.c \
+37
View File
@@ -32,6 +32,8 @@ extern "C" {
#endif
#include <rtems/score/tod.h>
#include <rtems/score/watchdog.h>
#include <rtems/rtems/status.h>
#include <rtems/rtems/types.h>
/*
@@ -122,6 +124,41 @@ rtems_status_code rtems_clock_set_nanoseconds_extension(
rtems_nanoseconds_extension_routine routine
);
/*
* rtems_clock_get_uptime
*
* DESCRIPTION:
*
* This directive returns the system uptime.
*
* Input parameters:
* routine - pointer to the time structure
*
* Output parameters:
* RTEMS_SUCCESSFUL - if successful
* error code - if unsuccessful
*/
rtems_status_code rtems_clock_get_uptime(
struct timespec *uptime
);
/** @brief _TOD_Validate
*
* This function returns TRUE if THE_TOD contains
* a valid time of day, and FALSE otherwise.
*/
boolean _TOD_Validate(
rtems_time_of_day *the_tod
);
/** @brief _TOD_To_seconds
*
* This function returns the number seconds between the epoch and THE_TOD.
*/
Watchdog_Interval _TOD_To_seconds(
rtems_time_of_day *the_tod
);
#ifdef __cplusplus
}
#endif
+1 -1
View File
@@ -41,8 +41,8 @@ extern "C" {
#endif
#include <rtems/score/object.h>
#include <rtems/score/tod.h>
#include <rtems/score/watchdog.h>
#include <rtems/rtems/clock.h>
#include <rtems/rtems/attr.h>
/*
+24 -1
View File
@@ -61,7 +61,30 @@ typedef Heap_Information_block region_information_block;
*/
typedef Watchdog_Interval rtems_interval;
typedef TOD_Control rtems_time_of_day;
/**
* The following record defines the time of control block. This
* control block is used to maintain the current time of day.
*
* @note This is an RTEID style time/date.
*/
typedef struct {
/** This field is the year, A.D. */
uint32_t year;
/** This field is the month, 1 -> 12 */
uint32_t month;
/** This field is the day, 1 -> 31 */
uint32_t day;
/** This field is the hour, 0 -> 23 */
uint32_t hour;
/** This field is the minute, 0 -> 59 */
uint32_t minute;
/** This field is the second, 0 -> 59 */
uint32_t second;
/** This field is the elapsed ticks between secs */
uint32_t ticks;
} rtems_time_of_day;
/*
* Define the type for an RTEMS API task mode.
+27 -17
View File
@@ -46,20 +46,35 @@ rtems_status_code rtems_clock_get(
void *time_buffer
)
{
ISR_Level level;
rtems_interval tmp;
if ( !time_buffer )
return RTEMS_INVALID_ADDRESS;
if ( !time_buffer )
return RTEMS_INVALID_ADDRESS;
switch ( option ) {
case RTEMS_CLOCK_GET_TOD:
case RTEMS_CLOCK_GET_TOD: {
struct tm time;
struct timeval now;
rtems_time_of_day *tmbuf = (rtems_time_of_day *)time_buffer;
if ( !_TOD_Is_set )
return RTEMS_NOT_DEFINED;
*(rtems_time_of_day *)time_buffer = _TOD_Current;
return RTEMS_SUCCESSFUL;
/* Obtain the current time */
_TOD_Get_timeval( &now );
/* Split it into a closer format */
gmtime_r( &now.tv_sec, &time );
/* Now adjust it to the RTEMS format */
tmbuf->year = time.tm_year + 1900;
tmbuf->month = time.tm_mon + 1;
tmbuf->day = time.tm_mday;
tmbuf->hour = time.tm_hour;
tmbuf->minute = time.tm_min;
tmbuf->second = time.tm_sec;
tmbuf->ticks = now.tv_usec / _TOD_Microseconds_per_tick;
return RTEMS_SUCCESSFUL;
}
case RTEMS_CLOCK_GET_SECONDS_SINCE_EPOCH:
if ( !_TOD_Is_set )
return RTEMS_NOT_DEFINED;
@@ -75,20 +90,15 @@ rtems_status_code rtems_clock_get(
*(rtems_interval *)time_buffer = _TOD_Ticks_per_second;
return RTEMS_SUCCESSFUL;
case RTEMS_CLOCK_GET_TIME_VALUE:
case RTEMS_CLOCK_GET_TIME_VALUE: {
struct timeval *time = (struct timeval *)time_buffer;
if ( !_TOD_Is_set )
return RTEMS_NOT_DEFINED;
_ISR_Disable( level );
((rtems_clock_time_value *)time_buffer)->seconds =
_TOD_Seconds_since_epoch;
tmp = _TOD_Current.ticks;
_ISR_Enable( level );
tmp *= _TOD_Microseconds_per_tick;
((rtems_clock_time_value *)time_buffer)->microseconds = tmp;
_TOD_Get_timeval( time );
return RTEMS_SUCCESSFUL;
}
}
return RTEMS_INTERNAL_ERROR; /* should never get here */
+50
View File
@@ -0,0 +1,50 @@
/*
* Clock Manager - get uptime
*
* COPYRIGHT (c) 1989-2007.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#if HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems/system.h>
#include <rtems/rtems/status.h>
#include <rtems/rtems/clock.h>
#include <rtems/score/isr.h>
#include <rtems/score/thread.h>
#include <rtems/score/tod.h>
#include <rtems/score/watchdog.h>
/*PAGE
*
* rtems_clock_get_uptime
*
* This directive obtains the system uptime. A timestamp is the seconds
* and nanoseconds since boot.
*
* Input parameters:
* timestamp - pointer to the timestamp
*
* Output parameters:
* *uptime - filled in
* RTEMS_SUCCESSFUL - if successful
* error code - if unsuccessful
*/
rtems_status_code rtems_clock_get_uptime(
struct timespec *uptime
)
{
if ( !uptime )
return RTEMS_INVALID_ADDRESS;
_TOD_Get_uptime( uptime );
return RTEMS_SUCCESSFUL;
}
+6 -3
View File
@@ -41,15 +41,18 @@ rtems_status_code rtems_clock_set(
rtems_time_of_day *time_buffer
)
{
rtems_interval seconds;
struct timespec newtime;
if ( !time_buffer )
return RTEMS_INVALID_ADDRESS;
if ( _TOD_Validate( time_buffer ) ) {
seconds = _TOD_To_seconds( time_buffer );
newtime.tv_sec = _TOD_To_seconds( time_buffer );
newtime.tv_nsec = time_buffer->ticks *
(_TOD_Microseconds_per_tick * TOD_NANOSECONDS_PER_MICROSECOND);
_Thread_Disable_dispatch();
_TOD_Set( time_buffer, seconds );
_TOD_Set( &newtime );
_Thread_Enable_dispatch();
return RTEMS_SUCCESSFUL;
}
+24 -7
View File
@@ -1,8 +1,8 @@
/*
* Time of Day (TOD) Handler
* Time of Day (TOD) Handler - Classic TOD to Seconds
*
*
* COPYRIGHT (c) 1989-1999.
* COPYRIGHT (c) 1989-2007.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
@@ -17,10 +17,27 @@
#endif
#include <rtems/system.h>
#include <rtems/score/object.h>
#include <rtems/score/thread.h>
#include <rtems/score/tod.h>
#include <rtems/score/watchdog.h>
#include <rtems/rtems/clock.h>
/*
* The following array contains the number of days in all months
* up to the month indicated by the index of the second dimension.
* The first dimension should be 1 for leap years, and 0 otherwise.
*/
const uint16_t _TOD_Days_to_date[2][13] = {
{ 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 },
{ 0, 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 }
};
/*
* The following array contains the number of days in the years
* since the last leap year. The index should be 0 for leap
* years, and the number of years since the beginning of a leap
* year otherwise.
*/
const uint16_t _TOD_Days_since_last_leap_year[4] = { 0, 366, 731, 1096 };
/*PAGE
*
@@ -37,7 +54,7 @@
*/
uint32_t _TOD_To_seconds(
TOD_Control *the_tod
rtems_time_of_day *the_tod
)
{
uint32_t time;
+15 -7
View File
@@ -1,8 +1,8 @@
/*
* Time of Day (TOD) Handler
* Time of Day (TOD) Handler -- Validate Classic TOD
*
*
* COPYRIGHT (c) 1989-1999.
* COPYRIGHT (c) 1989-2007.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
@@ -17,10 +17,18 @@
#endif
#include <rtems/system.h>
#include <rtems/score/object.h>
#include <rtems/score/thread.h>
#include <rtems/score/tod.h>
#include <rtems/score/watchdog.h>
#include <rtems/rtems/clock.h>
/*
* The following array contains the number of days in all months.
* The first dimension should be 1 for leap years, and 0 otherwise.
* The second dimension should range from 1 to 12 for January to
* February, respectively.
*/
const uint32_t _TOD_Days_per_month[ 2 ][ 13 ] = {
{ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
{ 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
};
/*PAGE
*
@@ -39,7 +47,7 @@
*/
boolean _TOD_Validate(
TOD_Control *the_tod
rtems_time_of_day *the_tod
)
{
uint32_t days_in_month;
+1
View File
@@ -20,6 +20,7 @@
#include <rtems/rtems/status.h>
#include <rtems/rtems/support.h>
#include <rtems/rtems/modes.h>
#include <rtems/rtems/clock.h>
#include <rtems/score/object.h>
#include <rtems/score/stack.h>
#include <rtems/score/states.h>
+4 -4
View File
@@ -140,12 +140,12 @@ libscore_a_SOURCES += src/threadq.c src/threadqdequeue.c \
src/threadqtimeout.c
## TOD_C_FILES
libscore_a_SOURCES += src/coretod.c src/coretodset.c src/coretodtickle.c \
src/coretodtoseconds.c src/coretodvalidate.c
libscore_a_SOURCES += src/coretod.c src/coretodset.c src/coretodget.c \
src/coretodgetuptime.c
## WATCHDOG_C_FILES
libscore_a_SOURCES += src/watchdog.c src/watchdogadjust.c src/watchdoginsert.c \
src/watchdogremove.c src/watchdogtickle.c
libscore_a_SOURCES += src/watchdog.c src/watchdogadjust.c \
src/watchdoginsert.c src/watchdogremove.c src/watchdogtickle.c
## STD_C_FILES
libscore_a_SOURCES += src/apiext.c src/chain.c \
+33 -111
View File
@@ -6,7 +6,7 @@
*/
/*
* COPYRIGHT (c) 1989-2006.
* COPYRIGHT (c) 1989-2007.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
@@ -32,6 +32,7 @@ extern "C" {
#include <rtems/score/object.h>
#include <rtems/score/watchdog.h>
#include <time.h>
/** @defgroup ScoreTODConstants TOD Constants
* The following constants are related to the time of day.
@@ -96,6 +97,15 @@ extern "C" {
*/
#define TOD_NANOSECONDS_PER_MICROSECOND (uint32_t)1000
/*
* Seconds from January 1, 1970 to January 1, 1988. Used to account for
* differences between POSIX API and RTEMS core. The timespec format time
* is kept in POSIX compliant form.
*/
#define TOD_SECONDS_1970_THROUGH_1988 \
(((1987 - 1970 + 1) * TOD_SECONDS_PER_NON_LEAP_YEAR) + \
(4 * TOD_SECONDS_PER_DAY))
/**@}*/
/** @brief RTEMS Epoch Year
@@ -106,29 +116,6 @@ extern "C" {
*/
#define TOD_BASE_YEAR 1988
/**
* The following record defines the time of control block. This
* control block is used to maintain the current time of day.
*
* @note This is an RTEID style time/date.
*/
typedef struct {
/** This field is the year, A.D. */
uint32_t year;
/** This field is the month, 1 -> 12 */
uint32_t month;
/** This field is the day, 1 -> 31 */
uint32_t day;
/** This field is the hour, 0 -> 23 */
uint32_t hour;
/** This field is the minute, 0 -> 59 */
uint32_t minute;
/** This field is the second, 0 -> 59 */
uint32_t second;
/** This field is the elapsed ticks between secs */
uint32_t ticks;
} TOD_Control;
/** @brief Is the Time Of Day Set
*
* This is TRUE if the application has set the current
@@ -136,10 +123,15 @@ typedef struct {
*/
SCORE_EXTERN boolean _TOD_Is_set;
/** @brief Current Time of Day
/** @brief Current Time of Day (Timespec)
* The following contains the current time of day.
*/
SCORE_EXTERN TOD_Control _TOD_Current;
SCORE_EXTERN struct timespec _TOD_Now;
/** @brief Current Time of Day (Timespec)
* The following contains the running uptime.
*/
SCORE_EXTERN struct timespec _TOD_Uptime;
/** @brief Seconds Since RTEMS Epoch
* The following contains the number of seconds from 00:00:00
@@ -164,69 +156,6 @@ SCORE_EXTERN uint32_t _TOD_Microseconds_per_tick;
*/
SCORE_EXTERN uint32_t _TOD_Ticks_per_second;
/** @brief Watchdog Set Managed by Seconds
*
* This is the control structure for the watchdog timer which
* fires to service the seconds chain.
*/
SCORE_EXTERN Watchdog_Control _TOD_Seconds_watchdog;
#ifdef SCORE_INIT
/*
* The following array contains the number of days in all months.
* The first dimension should be 1 for leap years, and 0 otherwise.
* The second dimension should range from 1 to 12 for January to
* February, respectively.
*/
const uint32_t _TOD_Days_per_month[ 2 ][ 13 ] = {
{ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
{ 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
};
/*
* The following array contains the number of days in all months
* up to the month indicated by the index of the second dimension.
* The first dimension should be 1 for leap years, and 0 otherwise.
*/
const uint16_t _TOD_Days_to_date[2][13] = {
{ 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 },
{ 0, 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 }
};
/*
* The following array contains the number of days in the years
* since the last leap year. The index should be 0 for leap
* years, and the number of years since the beginning of a leap
* year otherwise.
*/
const uint16_t _TOD_Days_since_last_leap_year[4] = { 0, 366, 731, 1096 };
#else
/** @brief Convert Month to Julian Days
*
* This is a prototype for a table which assists in converting the
* current day into the Julian days since the first of the year.
*/
extern const uint16_t _TOD_Days_to_date[2][13]; /* Julian days */
/** @brief Days since Beginning of Last Leap Year
*
* This is a prototype for a table which assists in calculating the
* number of days since the beginning of the last leap year.
*/
extern const uint16_t _TOD_Days_since_last_leap_year[4];
/** @brief Days Per Month Table
*
* This is a prototype for a table which holds the number of days
* per month for a leap year and non-leap year.
*/
extern const uint32_t _TOD_Days_per_month[2][13];
#endif
/** @brief _TOD_Handler_initialization
*
* This routine performs the initialization necessary for this handler.
@@ -237,40 +166,33 @@ void _TOD_Handler_initialization(
/** @brief _TOD_Set
*
* This routine sets the current time of day to THE_TOD and
* This routine sets the current time of day to @a time and
* the equivalent SECONDS_SINCE_EPOCH.
*/
void _TOD_Set(
TOD_Control *the_tod,
Watchdog_Interval seconds_since_epoch
const struct timespec *time
);
/** @brief _TOD_Validate
/** @brief _TOD_Get
*
* This function returns TRUE if THE_TOD contains
* a valid time of day, and FALSE otherwise.
* This routine returns the current time of day with potential accuracy
* to the nanosecond.
*
* @param[in] time is a pointer to the time to be returned
*/
boolean _TOD_Validate(
TOD_Control *the_tod
void _TOD_Get(
struct timespec *time
);
/** @brief _TOD_To_seconds
/** @brief _TOD_Get_uptime
*
* This function returns the number seconds between the epoch and THE_TOD.
*/
Watchdog_Interval _TOD_To_seconds(
TOD_Control *the_tod
);
/** @brief _TOD_Tickle
* This routine returns the system uptime with potential accuracy
* to the nanosecond.
*
* This routine is scheduled as a watchdog function and is invoked at
* each second boundary. It updates the current time of day to indicate
* that a second has passed and processes the seconds watchdog chain.
* @param[in] time is a pointer to the uptime to be returned
*/
void _TOD_Tickle(
Objects_Id id,
void *ignored
void _TOD_Get_uptime(
struct timespec *time
);
/** @brief TOD_MILLISECONDS_TO_MICROSECONDS
+71 -4
View File
@@ -6,7 +6,7 @@
*/
/*
* COPYRIGHT (c) 1989-2004.
* COPYRIGHT (c) 1989-2007.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
@@ -19,11 +19,41 @@
#ifndef _RTEMS_SCORE_TOD_INL
#define _RTEMS_SCORE_TOD_INL
#include <rtems/score/isr.h>
/**
* @addtogroup ScoreTOD
* @{
*/
/**
*
* This routines adds two timespecs. The second argument is added
* to the first.
*/
RTEMS_INLINE_ROUTINE uint32_t _TOD_Add_timespec(
struct timespec *time,
struct timespec *add
)
{
uint32_t seconds = 0;
/* Add the basics */
time->tv_sec += add->tv_sec;
time->tv_nsec += add->tv_nsec;
/* Now adjust it so nanoseconds is in range */
while ( time->tv_nsec >= TOD_NANOSECONDS_PER_SECOND ) {
time->tv_nsec -= TOD_NANOSECONDS_PER_SECOND;
time->tv_sec++;
seconds++;
}
return seconds;
}
/**
* This routine increments the ticks field of the current time of
* day at each clock tick.
@@ -31,8 +61,26 @@
RTEMS_INLINE_ROUTINE void _TOD_Tickle_ticks( void )
{
_TOD_Current.ticks += 1;
struct timespec tick;
uint32_t seconds;
/* Convert the tick quantum to a timespec */
tick.tv_nsec = _TOD_Microseconds_per_tick * 1000;
tick.tv_sec = 0;
/* Update the counter of ticks since boot */
_Watchdog_Ticks_since_boot += 1;
/* Update the timespec format uptime */
(void) _TOD_Add_timespec( &_TOD_Uptime, &tick );
/* we do not care how much the uptime changed */
/* Update the timespec format TOD */
seconds = _TOD_Add_timespec( &_TOD_Now, &tick );
while ( seconds ) {
_Watchdog_Tickle_seconds();
seconds--;
}
}
/**
@@ -41,7 +89,7 @@ RTEMS_INLINE_ROUTINE void _TOD_Tickle_ticks( void )
RTEMS_INLINE_ROUTINE void _TOD_Deactivate( void )
{
_Watchdog_Remove( &_TOD_Seconds_watchdog );
/* XXX do we need something now that we are using timespec for TOD */
}
/**
@@ -52,7 +100,26 @@ RTEMS_INLINE_ROUTINE void _TOD_Activate(
Watchdog_Interval ticks
)
{
_Watchdog_Insert_ticks( &_TOD_Seconds_watchdog, ticks );
/* XXX do we need something now that we are using timespec for TOD */
}
/**
* This routine returns a timeval based upon the internal timespec format TOD.
*/
RTEMS_INLINE_ROUTINE void _TOD_Get_timeval(
struct timeval *time
)
{
ISR_Level level;
struct timespec now;
_ISR_Disable(level);
_TOD_Get( &now );
_ISR_Enable(level);
time->tv_sec = now.tv_sec;
time->tv_usec = now.tv_nsec / TOD_NANOSECONDS_PER_MICROSECOND;
}
/**@}*/
+11 -10
View File
@@ -40,24 +40,25 @@ void _TOD_Handler_initialization(
{
_TOD_Microseconds_per_tick = microseconds_per_tick;
/* POSIX format TOD (timespec) */
_TOD_Now.tv_sec = TOD_SECONDS_1970_THROUGH_1988;
_TOD_Now.tv_nsec = 0;
/* Uptime (timespec) */
_TOD_Uptime.tv_sec = 0;
_TOD_Uptime.tv_nsec = 0;
/* Seconds since RTEMS Epoch (1988) */
_TOD_Seconds_since_epoch = 0;
_TOD_Current.year = TOD_BASE_YEAR;
_TOD_Current.month = 1;
_TOD_Current.day = 1;
_TOD_Current.hour = 0;
_TOD_Current.minute = 0;
_TOD_Current.second = 0;
_TOD_Current.ticks = 0;
/* Protect ourselves from a divide by zero fault */
if ( microseconds_per_tick == 0 )
_TOD_Ticks_per_second = 0;
else
_TOD_Ticks_per_second =
TOD_MICROSECONDS_PER_SECOND / microseconds_per_tick;
_Watchdog_Initialize( &_TOD_Seconds_watchdog, _TOD_Tickle, 0, NULL );
/* TOD has not been set */
_TOD_Is_set = FALSE;
_TOD_Activate( _TOD_Ticks_per_second );
}
+53
View File
@@ -0,0 +1,53 @@
/*
* Time of Day (TOD) Handler - get TOD
*
* COPYRIGHT (c) 1989-2007.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#if HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems/system.h>
#include <rtems/score/isr.h>
#include <rtems/score/tod.h>
/*
* _TOD_Get
*
* This routine is used to obtain the current date and time.
*
* Input parameters:
* time - pointer to the time and date structure
*
* Output parameters: NONE
*/
void _TOD_Get(
struct timespec *time
)
{
ISR_Level level;
struct timespec offset;
/* assume time checked by caller */
offset.tv_sec = 0;
offset.tv_nsec = 0;
/* _TOD_Now is a proper POSIX time */
_ISR_Disable( level );
*time = _TOD_Now;
if ( _Watchdog_Nanoseconds_since_tick_handler )
offset.tv_nsec = (*_Watchdog_Nanoseconds_since_tick_handler)();
_ISR_Enable( level );
_TOD_Add_timespec( time, &offset );
}
+52
View File
@@ -0,0 +1,52 @@
/*
* Time of Day (TOD) Handler - get uptime
*
* COPYRIGHT (c) 1989-2007.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#if HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems/system.h>
#include <rtems/score/isr.h>
#include <rtems/score/tod.h>
/*
* _TOD_Get_uptime
*
* This routine is used to obtain the system uptime
*
* Input parameters:
* time - pointer to the time and date structure
*
* Output parameters: NONE
*/
void _TOD_Get_uptime(
struct timespec *uptime
)
{
ISR_Level level;
struct timespec offset;
/* assume uptime checked by caller */
offset.tv_sec = 0;
offset.tv_nsec = 0;
_ISR_Disable( level );
*uptime = _TOD_Uptime;
if ( _Watchdog_Nanoseconds_since_tick_handler )
offset.tv_nsec = (*_Watchdog_Nanoseconds_since_tick_handler)();
_ISR_Enable( level );
_TOD_Add_timespec( uptime, &offset );
}
+12 -16
View File
@@ -30,37 +30,33 @@
* new date and time structure.
*
* Input parameters:
* the_tod - pointer to the time and date structure
* seconds_since_epoch - seconds since system epoch
* time - pointer to the time and date structure
*
* Output parameters: NONE
*/
void _TOD_Set(
TOD_Control *the_tod,
Watchdog_Interval seconds_since_epoch
const struct timespec *time
)
{
Watchdog_Interval ticks_until_next_second;
_Thread_Disable_dispatch();
_TOD_Deactivate();
if ( seconds_since_epoch < _TOD_Seconds_since_epoch )
if ( time->tv_sec < _TOD_Seconds_since_epoch )
_Watchdog_Adjust_seconds( WATCHDOG_BACKWARD,
_TOD_Seconds_since_epoch - seconds_since_epoch );
_TOD_Seconds_since_epoch - time->tv_sec );
else
_Watchdog_Adjust_seconds( WATCHDOG_FORWARD,
seconds_since_epoch - _TOD_Seconds_since_epoch );
time->tv_sec - _TOD_Seconds_since_epoch );
ticks_until_next_second = _TOD_Ticks_per_second;
if ( ticks_until_next_second > the_tod->ticks )
ticks_until_next_second -= the_tod->ticks;
_TOD_Current = *the_tod;
_TOD_Seconds_since_epoch = seconds_since_epoch;
_TOD_Seconds_since_epoch = time->tv_sec;
_TOD_Is_set = TRUE;
_TOD_Activate( ticks_until_next_second );
/* POSIX format TOD (timespec) */
_TOD_Now = *time;
_TOD_Now.tv_sec += TOD_SECONDS_1970_THROUGH_1988;
_TOD_Activate( 0 );
_Thread_Enable_dispatch();
}
-71
View File
@@ -1,71 +0,0 @@
/*
* Time of Day (TOD) Handler
*
*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#if HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems/system.h>
#include <rtems/score/object.h>
#include <rtems/score/thread.h>
#include <rtems/score/tod.h>
#include <rtems/score/watchdog.h>
/*PAGE
*
* _TOD_Tickle
*
* This routine updates the calendar time and tickles the
* per second watchdog timer chain.
*
* Input parameters:
* ignored - this parameter is ignored
*
* Output parameters: NONE
*
* NOTE: This routine only works for leap-years through 2099.
*/
void _TOD_Tickle(
Objects_Id id,
void *ignored
)
{
uint32_t leap;
_TOD_Current.ticks = 0;
++_TOD_Seconds_since_epoch;
if ( ++_TOD_Current.second >= TOD_SECONDS_PER_MINUTE ) {
_TOD_Current.second = 0;
if ( ++_TOD_Current.minute >= TOD_MINUTES_PER_HOUR ) {
_TOD_Current.minute = 0;
if ( ++_TOD_Current.hour >= TOD_HOURS_PER_DAY ) {
_TOD_Current.hour = 0;
if ( _TOD_Current.year & 0x3 ) leap = 0;
else leap = 1;
if ( ++_TOD_Current.day >
_TOD_Days_per_month[ leap ][ _TOD_Current.month ]) {
_TOD_Current.day = 1;
if ( ++_TOD_Current.month > TOD_MONTHS_PER_YEAR ) {
_TOD_Current.month = 1;
_TOD_Current.year++;
}
}
}
}
}
_Watchdog_Tickle_seconds();
_Watchdog_Insert_ticks( &_TOD_Seconds_watchdog, _TOD_Ticks_per_second );
}
-67
View File
@@ -1,67 +0,0 @@
/*
* Time of Day (TOD) Handler
*
*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#if HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems/system.h>
#include <rtems/score/object.h>
#include <rtems/score/thread.h>
#include <rtems/score/tod.h>
#include <rtems/score/watchdog.h>
/*PAGE
*
* _TOD_To_seconds
*
* This routine returns the seconds from the epoch until the
* current date and time.
*
* Input parameters:
* the_tod - pointer to the time and date structure
*
* Output parameters:
* returns - seconds since epoch until the_tod
*/
uint32_t _TOD_To_seconds(
TOD_Control *the_tod
)
{
uint32_t time;
uint32_t year_mod_4;
time = the_tod->day - 1;
year_mod_4 = the_tod->year & 3;
if ( year_mod_4 == 0 )
time += _TOD_Days_to_date[ 1 ][ the_tod->month ];
else
time += _TOD_Days_to_date[ 0 ][ the_tod->month ];
time += ( (the_tod->year - TOD_BASE_YEAR) / 4 ) *
( (TOD_DAYS_PER_YEAR * 4) + 1);
time += _TOD_Days_since_last_leap_year[ year_mod_4 ];
time *= TOD_SECONDS_PER_DAY;
time += ((the_tod->hour * TOD_MINUTES_PER_HOUR) + the_tod->minute)
* TOD_SECONDS_PER_MINUTE;
time += the_tod->second;
return( time );
}
-67
View File
@@ -1,67 +0,0 @@
/*
* Time of Day (TOD) Handler
*
*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#if HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems/system.h>
#include <rtems/score/object.h>
#include <rtems/score/thread.h>
#include <rtems/score/tod.h>
#include <rtems/score/watchdog.h>
/*PAGE
*
* _TOD_Validate
*
* This kernel routine checks the validity of a date and time structure.
*
* Input parameters:
* the_tod - pointer to a time and date structure
*
* Output parameters:
* TRUE - if the date, time, and tick are valid
* FALSE - if the the_tod is invalid
*
* NOTE: This routine only works for leap-years through 2099.
*/
boolean _TOD_Validate(
TOD_Control *the_tod
)
{
uint32_t days_in_month;
if ((!the_tod) ||
(the_tod->ticks >= _TOD_Ticks_per_second) ||
(the_tod->second >= TOD_SECONDS_PER_MINUTE) ||
(the_tod->minute >= TOD_MINUTES_PER_HOUR) ||
(the_tod->hour >= TOD_HOURS_PER_DAY) ||
(the_tod->month == 0) ||
(the_tod->month > TOD_MONTHS_PER_YEAR) ||
(the_tod->year < TOD_BASE_YEAR) ||
(the_tod->day == 0) )
return FALSE;
if ( (the_tod->year % 4) == 0 )
days_in_month = _TOD_Days_per_month[ 1 ][ the_tod->month ];
else
days_in_month = _TOD_Days_per_month[ 0 ][ the_tod->month ];
if ( the_tod->day > days_in_month )
return FALSE;
return TRUE;
}