$treeview $search $mathjax $extrastylesheet
avr-libc
2.0.0
$projectbrief
|
$projectbrief
|
$searchbox |
AVR Libc Home Page |
AVR Libc Development Pages |
||||
Main Page |
User Manual |
Library Reference |
FAQ |
Example Projects |
00001 /* 00002 * (C)2012 Michael Duane Rice All rights reserved. 00003 * 00004 * Redistribution and use in source and binary forms, with or without 00005 * modification, are permitted provided that the following conditions are 00006 * met: 00007 * 00008 * Redistributions of source code must retain the above copyright notice, this 00009 * list of conditions and the following disclaimer. Redistributions in binary 00010 * form must reproduce the above copyright notice, this list of conditions 00011 * and the following disclaimer in the documentation and/or other materials 00012 * provided with the distribution. Neither the name of the copyright holders 00013 * nor the names of contributors may be used to endorse or promote products 00014 * derived from this software without specific prior written permission. 00015 * 00016 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00017 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00018 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00019 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 00020 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00021 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00022 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00023 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00024 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00025 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00026 * POSSIBILITY OF SUCH DAMAGE. 00027 */ 00028 00029 /* $Id$ */ 00030 00031 /** \file */ 00032 00033 /** \defgroup avr_time <time.h>: Time 00034 \code #include <time.h> \endcode 00035 <h3>Introduction to the Time functions</h3> 00036 This file declares the time functions implemented in \c avr-libc. 00037 00038 The implementation aspires to conform with ISO/IEC 9899 (C90). However, due to limitations of the 00039 target processor and the nature of its development environment, a practical implementation must 00040 of necessity deviate from the standard. 00041 00042 00043 00044 Section 7.23.2.1 clock() 00045 The type clock_t, the macro CLOCKS_PER_SEC, and the function clock() are not implemented. We 00046 consider these items belong to operating system code, or to application code when no operating 00047 system is present. 00048 00049 Section 7.23.2.3 mktime() 00050 The standard specifies that mktime() should return (time_t) -1, if the time cannot be represented. 00051 This implementation always returns a 'best effort' representation. 00052 00053 Section 7.23.2.4 time() 00054 The standard specifies that time() should return (time_t) -1, if the time is not available. 00055 Since the application must initialize the time system, this functionality is not implemented. 00056 00057 Section 7.23.2.2, difftime() 00058 Due to the lack of a 64 bit double, the function difftime() returns a long integer. In most cases 00059 this change will be invisible to the user, handled automatically by the compiler. 00060 00061 Section 7.23.1.4 struct tm 00062 Per the standard, struct tm->tm_isdst is greater than zero when Daylight Saving time is in effect. 00063 This implementation further specifies that, when positive, the value of tm_isdst represents 00064 the amount time is advanced during Daylight Saving time. 00065 00066 Section 7.23.3.5 strftime() 00067 Only the 'C' locale is supported, therefore the modifiers 'E' and 'O' are ignored. 00068 The 'Z' conversion is also ignored, due to the lack of time zone name. 00069 00070 In addition to the above departures from the standard, there are some behaviors which are different 00071 from what is often expected, though allowed under the standard. 00072 00073 There is no 'platform standard' method to obtain the current time, time zone, or 00074 daylight savings 'rules' in the AVR environment. Therefore the application must initialize 00075 the time system with this information. The functions set_zone(), set_dst(), and 00076 set_system_time() are provided for initialization. Once initialized, system time is maintained by 00077 calling the function system_tick() at one second intervals. 00078 00079 Though not specified in the standard, it is often expected that time_t is a signed integer 00080 representing an offset in seconds from Midnight Jan 1 1970... i.e. 'Unix time'. This implementation 00081 uses an unsigned 32 bit integer offset from Midnight Jan 1 2000. The use of this 'epoch' helps to 00082 simplify the conversion functions, while the 32 bit value allows time to be properly represented 00083 until Tue Feb 7 06:28:15 2136 UTC. The macros UNIX_OFFSET and NTP_OFFSET are defined to assist in 00084 converting to and from Unix and NTP time stamps. 00085 00086 Unlike desktop counterparts, it is impractical to implement or maintain the 'zoneinfo' database. 00087 Therefore no attempt is made to account for time zone, daylight saving, or leap seconds in past dates. 00088 All calculations are made according to the currently configured time zone and daylight saving 'rule'. 00089 00090 In addition to C standard functions, re-entrant versions of ctime(), asctime(), gmtime() and 00091 localtime() are provided which, in addition to being re-entrant, have the property of claiming 00092 less permanent storage in RAM. An additional time conversion, isotime() and its re-entrant version, 00093 uses far less storage than either ctime() or asctime(). 00094 00095 Along with the usual smattering of utility functions, such as is_leap_year(), this library includes 00096 a set of functions related the sun and moon, as well as sidereal time functions. 00097 */ 00098 00099 #ifndef TIME_H 00100 #define TIME_H 00101 00102 #ifdef __cplusplus 00103 extern "C" { 00104 #endif 00105 00106 #include <inttypes.h> 00107 #include <stdlib.h> 00108 00109 /** \ingroup avr_time */ 00110 /* @{ */ 00111 00112 /** 00113 time_t represents seconds elapsed from Midnight, Jan 1 2000 UTC (the Y2K 'epoch'). 00114 Its range allows this implementation to represent time up to Tue Feb 7 06:28:15 2136 UTC. 00115 */ 00116 typedef uint32_t time_t; 00117 00118 /** 00119 The time function returns the systems current time stamp. 00120 If timer is not a null pointer, the return value is also assigned to the object it points to. 00121 */ 00122 time_t time(time_t *timer); 00123 00124 /** 00125 The difftime function returns the difference between two binary time stamps, 00126 time1 - time0. 00127 */ 00128 int32_t difftime(time_t time1, time_t time0); 00129 00130 00131 /** 00132 The tm structure contains a representation of time 'broken down' into components of the 00133 Gregorian calendar. 00134 00135 The value of tm_isdst is zero if Daylight Saving Time is not in effect, and is negative if 00136 the information is not available. 00137 00138 When Daylight Saving Time is in effect, the value represents the number of 00139 seconds the clock is advanced. 00140 00141 See the set_dst() function for more information about Daylight Saving. 00142 00143 */ 00144 struct tm { 00145 int8_t tm_sec; /**< seconds after the minute - [ 0 to 59 ] */ 00146 int8_t tm_min; /**< minutes after the hour - [ 0 to 59 ] */ 00147 int8_t tm_hour; /**< hours since midnight - [ 0 to 23 ] */ 00148 int8_t tm_mday; /**< day of the month - [ 1 to 31 ] */ 00149 int8_t tm_wday; /**< days since Sunday - [ 0 to 6 ] */ 00150 int8_t tm_mon; /**< months since January - [ 0 to 11 ] */ 00151 int16_t tm_year; /**< years since 1900 */ 00152 int16_t tm_yday; /**< days since January 1 - [ 0 to 365 ] */ 00153 int16_t tm_isdst; /**< Daylight Saving Time flag */ 00154 }; 00155 00156 #ifndef __DOXYGEN__ 00157 /* We have to provide clock_t / CLOCKS_PER_SEC so that libstdc++-v3 can 00158 be built. We define CLOCKS_PER_SEC via a symbol _CLOCKS_PER_SEC_ 00159 so that the user can provide the value on the link line, which should 00160 result in little or no run-time overhead compared with a constant. */ 00161 typedef unsigned long clock_t; 00162 extern char *_CLOCKS_PER_SEC_; 00163 #define CLOCKS_PER_SEC ((clock_t) _CLOCKS_PER_SEC_) 00164 extern clock_t clock(void); 00165 #endif /* !__DOXYGEN__ */ 00166 00167 /** 00168 This function 'compiles' the elements of a broken-down time structure, returning a binary time stamp. 00169 The elements of timeptr are interpreted as representing Local Time. 00170 00171 The original values of the tm_wday and tm_yday elements of the structure are ignored, 00172 and the original values of the other elements are not restricted to the ranges stated for struct tm. 00173 00174 On successful completion, the values of all elements of timeptr are set to the appropriate range. 00175 */ 00176 time_t mktime(struct tm * timeptr); 00177 00178 /** 00179 This function 'compiles' the elements of a broken-down time structure, returning a binary time stamp. 00180 The elements of timeptr are interpreted as representing UTC. 00181 00182 The original values of the tm_wday and tm_yday elements of the structure are ignored, 00183 and the original values of the other elements are not restricted to the ranges stated for struct tm. 00184 00185 Unlike mktime(), this function DOES NOT modify the elements of timeptr. 00186 */ 00187 time_t mk_gmtime(const struct tm * timeptr); 00188 00189 /** 00190 The gmtime function converts the time stamp pointed to by timer into broken-down time, 00191 expressed as UTC. 00192 */ 00193 struct tm *gmtime(const time_t * timer); 00194 00195 /** 00196 Re entrant version of gmtime(). 00197 */ 00198 void gmtime_r(const time_t * timer, struct tm * timeptr); 00199 00200 /** 00201 The localtime function converts the time stamp pointed to by timer into broken-down time, 00202 expressed as Local time. 00203 */ 00204 struct tm *localtime(const time_t * timer); 00205 00206 /** 00207 Re entrant version of localtime(). 00208 */ 00209 void localtime_r(const time_t * timer, struct tm * timeptr); 00210 00211 /** 00212 The asctime function converts the broken-down time of timeptr, into an ascii string in the form 00213 00214 Sun Mar 23 01:03:52 2013 00215 */ 00216 char *asctime(const struct tm * timeptr); 00217 00218 /** 00219 Re entrant version of asctime(). 00220 */ 00221 void asctime_r(const struct tm * timeptr, char *buf); 00222 00223 /** 00224 The ctime function is equivalent to asctime(localtime(timer)) 00225 */ 00226 char *ctime(const time_t * timer); 00227 00228 /** 00229 Re entrant version of ctime(). 00230 */ 00231 void ctime_r(const time_t * timer, char *buf); 00232 00233 /** 00234 The isotime function constructs an ascii string in the form 00235 \code2013-03-23 01:03:52\endcode 00236 */ 00237 char *isotime(const struct tm * tmptr); 00238 00239 /** 00240 Re entrant version of isotime() 00241 */ 00242 void isotime_r(const struct tm *, char *); 00243 00244 /** 00245 A complete description of strftime() is beyond the pale of this document. 00246 Refer to ISO/IEC document 9899 for details. 00247 00248 All conversions are made using the 'C Locale', ignoring the E or O modifiers. Due to the lack of 00249 a time zone 'name', the 'Z' conversion is also ignored. 00250 */ 00251 size_t strftime(char *s, size_t maxsize, const char *format, const struct tm * timeptr); 00252 00253 /** 00254 Specify the Daylight Saving function. 00255 00256 The Daylight Saving function should examine its parameters to determine whether 00257 Daylight Saving is in effect, and return a value appropriate for tm_isdst. 00258 00259 Working examples for the USA and the EU are available.. 00260 00261 \code #include <util/eu_dst.h>\endcode 00262 for the European Union, and 00263 \code #include <util/usa_dst.h>\endcode 00264 for the United States 00265 00266 If a Daylight Saving function is not specified, the system will ignore Daylight Saving. 00267 */ 00268 void set_dst(int (*) (const time_t *, int32_t *)); 00269 00270 /** 00271 Set the 'time zone'. The parameter is given in seconds East of the Prime Meridian. 00272 Example for New York City: 00273 \code set_zone(-5 * ONE_HOUR);\endcode 00274 00275 If the time zone is not set, the time system will operate in UTC only. 00276 */ 00277 void set_zone(int32_t); 00278 00279 /** 00280 Initialize the system time. Examples are... 00281 00282 From a Clock / Calendar type RTC: 00283 \code 00284 struct tm rtc_time; 00285 00286 read_rtc(&rtc_time); 00287 rtc_time.tm_isdst = 0; 00288 set_system_time( mktime(&rtc_time) ); 00289 \endcode 00290 00291 From a Network Time Protocol time stamp: 00292 \code 00293 set_system_time(ntp_timestamp - NTP_OFFSET); 00294 \endcode 00295 00296 From a UNIX time stamp: 00297 \code 00298 set_system_time(unix_timestamp - UNIX_OFFSET); 00299 \endcode 00300 00301 */ 00302 void set_system_time(time_t timestamp); 00303 00304 /** 00305 Maintain the system time by calling this function at a rate of 1 Hertz. 00306 00307 It is anticipated that this function will typically be called from within an 00308 Interrupt Service Routine, (though that is not required). It therefore includes code which 00309 makes it simple to use from within a 'Naked' ISR, avoiding the cost of saving and restoring 00310 all the cpu registers. 00311 00312 Such an ISR may resemble the following example... 00313 \code 00314 ISR(RTC_OVF_vect, ISR_NAKED) 00315 { 00316 system_tick(); 00317 reti(); 00318 } 00319 \endcode 00320 */ 00321 void system_tick(void); 00322 00323 /** 00324 Enumerated labels for the days of the week. 00325 */ 00326 enum _WEEK_DAYS_ { 00327 SUNDAY, 00328 MONDAY, 00329 TUESDAY, 00330 WEDNESDAY, 00331 THURSDAY, 00332 FRIDAY, 00333 SATURDAY 00334 }; 00335 00336 /** 00337 Enumerated labels for the months. 00338 */ 00339 enum _MONTHS_ { 00340 JANUARY, 00341 FEBRUARY, 00342 MARCH, 00343 APRIL, 00344 MAY, 00345 JUNE, 00346 JULY, 00347 AUGUST, 00348 SEPTEMBER, 00349 OCTOBER, 00350 NOVEMBER, 00351 DECEMBER 00352 }; 00353 00354 /** 00355 Return 1 if year is a leap year, zero if it is not. 00356 */ 00357 uint8_t is_leap_year(int16_t year); 00358 00359 /** 00360 Return the length of month, given the year and month, where month is in the range 1 to 12. 00361 */ 00362 uint8_t month_length(int16_t year, uint8_t month); 00363 00364 /** 00365 Return the calendar week of year, where week 1 is considered to begin on the 00366 day of week specified by 'start'. The returned value may range from zero to 52. 00367 */ 00368 uint8_t week_of_year(const struct tm * timeptr, uint8_t start); 00369 00370 /** 00371 Return the calendar week of month, where the first week is considered to begin on the 00372 day of week specified by 'start'. The returned value may range from zero to 5. 00373 */ 00374 uint8_t week_of_month(const struct tm * timeptr, uint8_t start); 00375 00376 /** 00377 Structure which represents a date as a year, week number of that year, and day of week. 00378 See http://en.wikipedia.org/wiki/ISO_week_date for more information. 00379 */ 00380 struct week_date { 00381 int year; /**< year number (Gregorian calendar) */ 00382 int week; /**< week number (#1 is where first Thursday is in) */ 00383 int day; /**< day within week */ 00384 }; 00385 00386 /** 00387 Return a week_date structure with the ISO_8601 week based date corresponding to the given 00388 year and day of year. See http://en.wikipedia.org/wiki/ISO_week_date for more 00389 information. 00390 */ 00391 struct week_date * iso_week_date( int year, int yday); 00392 00393 /** 00394 Re-entrant version of iso-week_date. 00395 */ 00396 void iso_week_date_r( int year, int yday, struct week_date *); 00397 00398 /** 00399 Convert a Y2K time stamp into a FAT file system time stamp. 00400 */ 00401 uint32_t fatfs_time(const struct tm * timeptr); 00402 00403 /** One hour, expressed in seconds */ 00404 #define ONE_HOUR 3600 00405 00406 /** Angular degree, expressed in arc seconds */ 00407 #define ONE_DEGREE 3600 00408 00409 /** One day, expressed in seconds */ 00410 #define ONE_DAY 86400 00411 00412 /** Difference between the Y2K and the UNIX epochs, in seconds. To convert a Y2K 00413 timestamp to UNIX... 00414 \code 00415 long unix; 00416 time_t y2k; 00417 00418 y2k = time(NULL); 00419 unix = y2k + UNIX_OFFSET; 00420 \endcode 00421 */ 00422 #define UNIX_OFFSET 946684800 00423 00424 /** Difference between the Y2K and the NTP epochs, in seconds. To convert a Y2K 00425 timestamp to NTP... 00426 \code 00427 unsigned long ntp; 00428 time_t y2k; 00429 00430 y2k = time(NULL); 00431 ntp = y2k + NTP_OFFSET; 00432 \endcode 00433 */ 00434 #define NTP_OFFSET 3155673600 00435 00436 /* 00437 * =================================================================== 00438 * Ephemera 00439 */ 00440 00441 /** 00442 Set the geographic coordinates of the 'observer', for use with several of the 00443 following functions. Parameters are passed as seconds of North Latitude, and seconds 00444 of East Longitude. 00445 00446 For New York City... 00447 \code set_position( 40.7142 * ONE_DEGREE, -74.0064 * ONE_DEGREE); \endcode 00448 */ 00449 void set_position(int32_t latitude, int32_t longitude); 00450 00451 /** 00452 Computes the difference between apparent solar time and mean solar time. 00453 The returned value is in seconds. 00454 */ 00455 int16_t equation_of_time(const time_t * timer); 00456 00457 /** 00458 Computes the amount of time the sun is above the horizon, at the location of the observer. 00459 00460 NOTE: At observer locations inside a polar circle, this value can be zero during the winter, 00461 and can exceed ONE_DAY during the summer. 00462 00463 The returned value is in seconds. 00464 */ 00465 int32_t daylight_seconds(const time_t * timer); 00466 00467 /** 00468 Computes the time of solar noon, at the location of the observer. 00469 */ 00470 time_t solar_noon(const time_t * timer); 00471 00472 /** 00473 Return the time of sunrise, at the location of the observer. See the note about daylight_seconds(). 00474 */ 00475 time_t sun_rise(const time_t * timer); 00476 00477 /** 00478 Return the time of sunset, at the location of the observer. See the note about daylight_seconds(). 00479 */ 00480 time_t sun_set(const time_t * timer); 00481 00482 /** Returns the declination of the sun in radians. */ 00483 double solar_declination(const time_t * timer); 00484 00485 /** 00486 Returns an approximation to the phase of the moon. 00487 The sign of the returned value indicates a waning or waxing phase. 00488 The magnitude of the returned value indicates the percentage illumination. 00489 */ 00490 int8_t moon_phase(const time_t * timer); 00491 00492 /** 00493 Returns Greenwich Mean Sidereal Time, as seconds into the sidereal day. 00494 The returned value will range from 0 through 86399 seconds. 00495 */ 00496 unsigned long gm_sidereal(const time_t * timer); 00497 00498 /** 00499 Returns Local Mean Sidereal Time, as seconds into the sidereal day. 00500 The returned value will range from 0 through 86399 seconds. 00501 */ 00502 unsigned long lm_sidereal(const time_t * timer); 00503 00504 /* @} */ 00505 #ifdef __cplusplus 00506 } 00507 #endif 00508 00509 #endif /* TIME_H */