source: rtems/cpukit/rtems/src/clockgettod.c @ 66cb142

Last change on this file since 66cb142 was eae0863, checked in by Chris Johns <chrisj@…>, on Apr 27, 2014 at 8:11:09 AM

rtems: Fix sp2038 test.

Avoid using newlib's gmtime_r call which fails with a max signed int.
Add an RTEMS specific version for 1/1/1988 to 31/12/2100.

Update sp2038 to test every day from 1/1/1988 to 31/12/2100. Only days
need be tested as the code splits the seconds based on days.

  • Property mode set to 100644
File size: 3.2 KB
Line 
1/**
2 * @file
3 *
4 * @brief Obtain Current Time of Day (Classic TOD)
5 * @ingroup ClassicClock Clocks
6 */
7
8/*
9 *  COPYRIGHT (c) 1989-2007.
10 *  On-Line Applications Research Corporation (OAR).
11 *
12 *  The license and distribution terms for this file may be
13 *  found in the file LICENSE in this distribution or at
14 *  http://www.rtems.org/license/LICENSE.
15 */
16
17#if HAVE_CONFIG_H
18#include "config.h"
19#endif
20
21#include <rtems/rtems/clock.h>
22#include <rtems/score/todimpl.h>
23#include <rtems/config.h>
24
25#define RTEMS_SECS_PER_MINUTE (60UL)
26#define RTEMS_MINUTE_PER_HOUR (60UL)
27#define RTEMS_SECS_PER_HOUR   (RTEMS_SECS_PER_MINUTE * RTEMS_MINUTE_PER_HOUR)
28#define RTEMS_HOURS_PER_DAY   (24UL)
29#define RTEMS_SECS_PER_DAY    (RTEMS_SECS_PER_HOUR * RTEMS_HOURS_PER_DAY)
30#define RTEMS_DAYS_PER_YEAR   (365UL)
31#define RTEMS_YEAR_BASE       (1970UL)
32
33extern const uint16_t _TOD_Days_to_date[2][13];
34
35static bool _Leap_year(
36  uint32_t year
37)
38{
39  return (((year % 4) == 0) && ((year % 100) != 0)) || ((year % 400) == 0);
40}
41
42static uint32_t _Leap_years_before(
43  uint32_t year
44)
45{
46  year -= 1;
47  return (year / 4) - (year / 100) + (year / 400);
48}
49
50static uint32_t _Leap_years_between(
51  uint32_t from, uint32_t to
52)
53{
54  return _Leap_years_before( to ) - _Leap_years_before( from + 1 );
55}
56
57static uint32_t _Year_day_as_month(
58  uint32_t year, uint32_t *day
59)
60{
61  const uint16_t* days_to_date;
62  uint32_t        month = 0;
63
64  if ( _Leap_year( year ) )
65    days_to_date = _TOD_Days_to_date[1];
66  else
67    days_to_date = _TOD_Days_to_date[0];
68
69  days_to_date += 2;
70
71  while (month < 11) {
72    if (*day < *days_to_date)
73      break;
74    ++month;
75    ++days_to_date;
76  }
77
78  *day -= *(days_to_date - 1);
79
80  return month;
81}
82
83rtems_status_code rtems_clock_get_tod(
84  rtems_time_of_day  *time_buffer
85)
86{
87  struct timeval now;
88  uint32_t       days;
89  uint32_t       day_secs;
90  uint32_t       year;
91  uint32_t       year_days;
92  uint32_t       leap_years;
93
94  if ( !time_buffer )
95    return RTEMS_INVALID_ADDRESS;
96
97  if ( !_TOD_Is_set() )
98    return RTEMS_NOT_DEFINED;
99
100  /* Obtain the current time */
101  _TOD_Get_timeval( &now );
102
103  /* How many days and how many seconds in the day ? */
104  days = now.tv_sec / RTEMS_SECS_PER_DAY;
105  day_secs = now.tv_sec % RTEMS_SECS_PER_DAY;
106
107  /* How many non-leap year years ? */
108  year = ( days / RTEMS_DAYS_PER_YEAR ) + RTEMS_YEAR_BASE;
109
110  /* Determine the number of leap years. */
111  leap_years = _Leap_years_between( RTEMS_YEAR_BASE, year );
112
113  /* Adjust the remaining number of days based on the leap years. */
114  year_days = ( days - leap_years ) % RTEMS_DAYS_PER_YEAR;
115
116  /* Adjust the year and days in the year if in the leap year overflow. */
117  if ( leap_years > ( days % RTEMS_DAYS_PER_YEAR ) ) {
118    year -= 1;
119    if ( _Leap_year( year ) ) {
120      year_days += 1;
121    }
122  }
123
124  time_buffer->year   = year;
125  time_buffer->month  = _Year_day_as_month( year, &year_days ) + 1;
126  time_buffer->day    = year_days + 1;
127  time_buffer->hour   = day_secs / RTEMS_SECS_PER_HOUR;
128  time_buffer->minute = day_secs % RTEMS_SECS_PER_HOUR;
129  time_buffer->second = time_buffer->minute % RTEMS_SECS_PER_MINUTE;
130  time_buffer->minute = time_buffer->minute / RTEMS_SECS_PER_MINUTE;
131  time_buffer->ticks  = now.tv_usec /
132    rtems_configuration_get_microseconds_per_tick( );
133
134  return RTEMS_SUCCESSFUL;
135}
Note: See TracBrowser for help on using the repository browser.