source: rtems/c/src/exec/score/src/tod.c @ 65c421f

4.104.114.84.95
Last change on this file since 65c421f was 5e7b6272, checked in by Joel Sherrill <joel.sherrill@…>, on 05/31/96 at 23:27:45

renamed _TOD_Ticks_since_boot as _Watchdog_Ticks_since_boot so the Watchdog
Handler could timestamp the starting and stopping of timers. Since
TOD is built on top of Watchdog, this avoided a circular dependency.

  • Property mode set to 100644
File size: 5.6 KB
Line 
1/*
2 *  Time of Day (TOD) Handler
3 *
4 *
5 *  COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
6 *  On-Line Applications Research Corporation (OAR).
7 *  All rights assigned to U.S. Government, 1994.
8 *
9 *  This material may be reproduced by or for the U.S. Government pursuant
10 *  to the copyright license under the clause at DFARS 252.227-7013.  This
11 *  notice must appear in all copies of this file and its derivatives.
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
59/*PAGE
60 *
61 *  _TOD_Set
62 *
63 *  This rountine sets the current date and time with the specified
64 *  new date and time structure.
65 *
66 *  Input parameters:
67 *    the_tod             - pointer to the time and date structure
68 *    seconds_since_epoch - seconds since system epoch
69 *
70 *  Output parameters: NONE
71 */
72
73void _TOD_Set(
74  TOD_Control *the_tod,
75  Watchdog_Interval  seconds_since_epoch
76)
77{
78  Watchdog_Interval ticks_until_next_second;
79
80  _Thread_Disable_dispatch();
81  _TOD_Deactivate();
82
83  if ( seconds_since_epoch < _TOD_Seconds_since_epoch )
84    _Watchdog_Adjust_seconds( WATCHDOG_BACKWARD,
85       _TOD_Seconds_since_epoch - seconds_since_epoch );
86  else
87    _Watchdog_Adjust_seconds( WATCHDOG_FORWARD,
88       seconds_since_epoch - _TOD_Seconds_since_epoch );
89
90  ticks_until_next_second = _TOD_Ticks_per_second;
91  if ( ticks_until_next_second > _TOD_Current.ticks )
92    ticks_until_next_second -= _TOD_Current.ticks;
93
94  _TOD_Current             = *the_tod;
95  _TOD_Seconds_since_epoch = seconds_since_epoch;
96  _TOD_Activate( ticks_until_next_second );
97
98  _Thread_Enable_dispatch();
99}
100
101/*PAGE
102 *
103 *  _TOD_Validate
104 *
105 *  This kernel routine checks the validity of a date and time structure.
106 *
107 *  Input parameters:
108 *    the_tod - pointer to a time and date structure
109 *
110 *  Output parameters:
111 *    TRUE  - if the date, time, and tick are valid
112 *    FALSE - if the the_tod is invalid
113 *
114 *  NOTE: This routine only works for leap-years through 2099.
115 */
116
117boolean _TOD_Validate(
118  TOD_Control *the_tod
119)
120{
121  unsigned32 days_in_month;
122
123  if ((the_tod->ticks  >= _TOD_Ticks_per_second)  ||
124      (the_tod->second >= TOD_SECONDS_PER_MINUTE) ||
125      (the_tod->minute >= TOD_MINUTES_PER_HOUR)   ||
126      (the_tod->hour   >= TOD_HOURS_PER_DAY)      ||
127      (the_tod->month  == 0)                      ||
128      (the_tod->month  >  TOD_MONTHS_PER_YEAR)    ||
129      (the_tod->year   <  TOD_BASE_YEAR)          ||
130      (the_tod->day    == 0) )
131     return FALSE;
132
133  if ( (the_tod->year % 4) == 0 )
134    days_in_month = _TOD_Days_per_month[ 1 ][ the_tod->month ];
135  else
136    days_in_month = _TOD_Days_per_month[ 0 ][ the_tod->month ];
137
138  if ( the_tod->day > days_in_month )
139    return FALSE;
140
141  return TRUE;
142}
143
144/*PAGE
145 *
146 *  _TOD_To_seconds
147 *
148 *  This routine returns the seconds from the epoch until the
149 *  current date and time.
150 *
151 *  Input parameters:
152 *    the_tod - pointer to the time and date structure
153 *
154 *  Output parameters:
155 *    returns    - seconds since epoch until the_tod
156 */
157
158unsigned32 _TOD_To_seconds(
159  TOD_Control *the_tod
160)
161{
162  unsigned32 time;
163  unsigned32 year_mod_4;
164
165  time = the_tod->day - 1;
166  year_mod_4 = the_tod->year & 3;
167
168  if ( year_mod_4 == 0 )
169    time += _TOD_Days_to_date[ 1 ][ the_tod->month ];
170  else
171    time += _TOD_Days_to_date[ 0 ][ the_tod->month ];
172
173  time += ( (the_tod->year - TOD_BASE_YEAR) / 4 ) *
174            ( (TOD_DAYS_PER_YEAR * 4) + 1);
175
176  time += _TOD_Days_since_last_leap_year[ year_mod_4 ];
177
178  time *= TOD_SECONDS_PER_DAY;
179
180  time += ((the_tod->hour * TOD_MINUTES_PER_HOUR) + the_tod->minute)
181             * TOD_SECONDS_PER_MINUTE;
182
183  time += the_tod->second;
184
185  return( time );
186}
187
188/*PAGE
189 *
190 *  _TOD_Tickle
191 *
192 *  This routine updates the calendar time and tickles the
193 *  per second watchdog timer chain.
194 *
195 *  Input parameters:
196 *    ignored - this parameter is ignored
197 *
198 *  Output parameters: NONE
199 *
200 *  NOTE: This routine only works for leap-years through 2099.
201 */
202
203void _TOD_Tickle(
204  Objects_Id  id,
205  void       *ignored
206)
207{
208  unsigned32 leap;
209
210  _TOD_Current.ticks = 0;
211  ++_TOD_Seconds_since_epoch;
212  if ( ++_TOD_Current.second >= TOD_SECONDS_PER_MINUTE ) {
213    _TOD_Current.second = 0;
214    if ( ++_TOD_Current.minute >= TOD_MINUTES_PER_HOUR ) {
215      _TOD_Current.minute = 0;
216      if ( ++_TOD_Current.hour >= TOD_HOURS_PER_DAY ) {
217        _TOD_Current.hour = 0;
218        if ( _TOD_Current.year & 0x3 ) leap = 0;
219        else                           leap = 1;
220        if ( ++_TOD_Current.day >
221               _TOD_Days_per_month[ leap ][ _TOD_Current.month ]) {
222          _TOD_Current.day = 1;
223          if ( ++_TOD_Current.month > TOD_MONTHS_PER_YEAR ) {
224            _TOD_Current.month = 1;
225            _TOD_Current.year++;
226          }
227        }
228      }
229    }
230  }
231
232  _Watchdog_Tickle_seconds();
233  _Watchdog_Insert_ticks( &_TOD_Seconds_watchdog, _TOD_Ticks_per_second );
234}
Note: See TracBrowser for help on using the repository browser.