source: rtems/cpukit/score/src/coretod.c @ 03f2154e

4.104.114.84.95
Last change on this file since 03f2154e was 03f2154e, checked in by Joel Sherrill <joel.sherrill@…>, on 04/22/97 at 17:20:27

headers updated to reflect new style copyright notice as part
of switching to the modified GNU GPL.

  • Property mode set to 100644
File size: 5.6 KB
Line 
1/*
2 *  Time of Day (TOD) Handler
3 *
4 *
5 *  COPYRIGHT (c) 1989-1997.
6 *  On-Line Applications Research Corporation (OAR).
7 *  Copyright assigned to U.S. Government, 1994.
8 *
9 *  The license and distribution terms for this file may in
10 *  the file LICENSE in this distribution or at
11 *  http://www.OARcorp.com/rtems/license.html.
12 *
13 *  $Id$
14 */
15
16#include <rtems/system.h>
17#include <rtems/score/object.h>
18#include <rtems/score/thread.h>
19#include <rtems/score/tod.h>
20#include <rtems/score/watchdog.h>
21
22/*PAGE
23 *
24 *  _TOD_Handler_initialization
25 *
26 *  This routine initializes the time of day handler.
27 *
28 *  Input parameters:
29 *    microseconds_per_tick - microseconds between clock ticks
30 *
31 *  Output parameters: NONE
32 */
33
34void _TOD_Handler_initialization(
35  unsigned32 microseconds_per_tick
36)
37{
38  _TOD_Microseconds_per_tick = microseconds_per_tick;
39
40  _TOD_Seconds_since_epoch = 0;
41
42  _TOD_Current.year   = TOD_BASE_YEAR;
43  _TOD_Current.month  = 1;
44  _TOD_Current.day    = 1;
45  _TOD_Current.hour   = 0;
46  _TOD_Current.minute = 0;
47  _TOD_Current.second = 0;
48  _TOD_Current.ticks  = 0;
49
50  if ( microseconds_per_tick == 0 )
51    _TOD_Ticks_per_second = 0;
52  else
53    _TOD_Ticks_per_second =
54       TOD_MICROSECONDS_PER_SECOND / microseconds_per_tick;
55
56  _Watchdog_Initialize( &_TOD_Seconds_watchdog, _TOD_Tickle, 0, NULL );
57
58  _TOD_Is_set = FALSE;
59  _TOD_Activate( _TOD_Ticks_per_second );
60}
61
62/*PAGE
63 *
64 *  _TOD_Set
65 *
66 *  This rountine sets the current date and time with the specified
67 *  new date and time structure.
68 *
69 *  Input parameters:
70 *    the_tod             - pointer to the time and date structure
71 *    seconds_since_epoch - seconds since system epoch
72 *
73 *  Output parameters: NONE
74 */
75
76void _TOD_Set(
77  TOD_Control *the_tod,
78  Watchdog_Interval  seconds_since_epoch
79)
80{
81  Watchdog_Interval ticks_until_next_second;
82
83  _Thread_Disable_dispatch();
84  _TOD_Deactivate();
85
86  if ( seconds_since_epoch < _TOD_Seconds_since_epoch )
87    _Watchdog_Adjust_seconds( WATCHDOG_BACKWARD,
88       _TOD_Seconds_since_epoch - seconds_since_epoch );
89  else
90    _Watchdog_Adjust_seconds( WATCHDOG_FORWARD,
91       seconds_since_epoch - _TOD_Seconds_since_epoch );
92
93  ticks_until_next_second = _TOD_Ticks_per_second;
94  if ( ticks_until_next_second > _TOD_Current.ticks )
95    ticks_until_next_second -= _TOD_Current.ticks;
96
97  _TOD_Current             = *the_tod;
98  _TOD_Seconds_since_epoch = seconds_since_epoch;
99  _TOD_Is_set              = TRUE;
100  _TOD_Activate( ticks_until_next_second );
101
102  _Thread_Enable_dispatch();
103}
104
105/*PAGE
106 *
107 *  _TOD_Validate
108 *
109 *  This kernel routine checks the validity of a date and time structure.
110 *
111 *  Input parameters:
112 *    the_tod - pointer to a time and date structure
113 *
114 *  Output parameters:
115 *    TRUE  - if the date, time, and tick are valid
116 *    FALSE - if the the_tod is invalid
117 *
118 *  NOTE: This routine only works for leap-years through 2099.
119 */
120
121boolean _TOD_Validate(
122  TOD_Control *the_tod
123)
124{
125  unsigned32 days_in_month;
126
127  if ((the_tod->ticks  >= _TOD_Ticks_per_second)  ||
128      (the_tod->second >= TOD_SECONDS_PER_MINUTE) ||
129      (the_tod->minute >= TOD_MINUTES_PER_HOUR)   ||
130      (the_tod->hour   >= TOD_HOURS_PER_DAY)      ||
131      (the_tod->month  == 0)                      ||
132      (the_tod->month  >  TOD_MONTHS_PER_YEAR)    ||
133      (the_tod->year   <  TOD_BASE_YEAR)          ||
134      (the_tod->day    == 0) )
135     return FALSE;
136
137  if ( (the_tod->year % 4) == 0 )
138    days_in_month = _TOD_Days_per_month[ 1 ][ the_tod->month ];
139  else
140    days_in_month = _TOD_Days_per_month[ 0 ][ the_tod->month ];
141
142  if ( the_tod->day > days_in_month )
143    return FALSE;
144
145  return TRUE;
146}
147
148/*PAGE
149 *
150 *  _TOD_To_seconds
151 *
152 *  This routine returns the seconds from the epoch until the
153 *  current date and time.
154 *
155 *  Input parameters:
156 *    the_tod - pointer to the time and date structure
157 *
158 *  Output parameters:
159 *    returns    - seconds since epoch until the_tod
160 */
161
162unsigned32 _TOD_To_seconds(
163  TOD_Control *the_tod
164)
165{
166  unsigned32 time;
167  unsigned32 year_mod_4;
168
169  time = the_tod->day - 1;
170  year_mod_4 = the_tod->year & 3;
171
172  if ( year_mod_4 == 0 )
173    time += _TOD_Days_to_date[ 1 ][ the_tod->month ];
174  else
175    time += _TOD_Days_to_date[ 0 ][ the_tod->month ];
176
177  time += ( (the_tod->year - TOD_BASE_YEAR) / 4 ) *
178            ( (TOD_DAYS_PER_YEAR * 4) + 1);
179
180  time += _TOD_Days_since_last_leap_year[ year_mod_4 ];
181
182  time *= TOD_SECONDS_PER_DAY;
183
184  time += ((the_tod->hour * TOD_MINUTES_PER_HOUR) + the_tod->minute)
185             * TOD_SECONDS_PER_MINUTE;
186
187  time += the_tod->second;
188
189  return( time );
190}
191
192/*PAGE
193 *
194 *  _TOD_Tickle
195 *
196 *  This routine updates the calendar time and tickles the
197 *  per second watchdog timer chain.
198 *
199 *  Input parameters:
200 *    ignored - this parameter is ignored
201 *
202 *  Output parameters: NONE
203 *
204 *  NOTE: This routine only works for leap-years through 2099.
205 */
206
207void _TOD_Tickle(
208  Objects_Id  id,
209  void       *ignored
210)
211{
212  unsigned32 leap;
213
214  _TOD_Current.ticks = 0;
215  ++_TOD_Seconds_since_epoch;
216  if ( ++_TOD_Current.second >= TOD_SECONDS_PER_MINUTE ) {
217    _TOD_Current.second = 0;
218    if ( ++_TOD_Current.minute >= TOD_MINUTES_PER_HOUR ) {
219      _TOD_Current.minute = 0;
220      if ( ++_TOD_Current.hour >= TOD_HOURS_PER_DAY ) {
221        _TOD_Current.hour = 0;
222        if ( _TOD_Current.year & 0x3 ) leap = 0;
223        else                           leap = 1;
224        if ( ++_TOD_Current.day >
225               _TOD_Days_per_month[ leap ][ _TOD_Current.month ]) {
226          _TOD_Current.day = 1;
227          if ( ++_TOD_Current.month > TOD_MONTHS_PER_YEAR ) {
228            _TOD_Current.month = 1;
229            _TOD_Current.year++;
230          }
231        }
232      }
233    }
234  }
235
236  _Watchdog_Tickle_seconds();
237  _Watchdog_Insert_ticks( &_TOD_Seconds_watchdog, _TOD_Ticks_per_second );
238}
Note: See TracBrowser for help on using the repository browser.