localtime.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. /*
  2. ********************************************************************************
  3. **
  4. ** \file ./boot/startup/src/localtime.c
  5. **
  6. ** \version $Id: localtime.c 6304 2016-03-18 03:39:06Z chenke $
  7. **
  8. ** \brief ARM1176 RealView libc function retargeting.
  9. **
  10. ** This files retargets the time-specific function localtime().
  11. **
  12. ** \attention THIS SAMPLE CODE IS PROVIDED AS IS. FUJITSU MICROELECTRONICS
  13. ** ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
  14. ** OMMISSIONS.
  15. **
  16. ** (C) Copyright 2006-2010 by Fujitsu Microelectronics Europe GmbH
  17. ** (C) Copyright 2010 by Fujitsu Semiconductor Europe GmbH
  18. **
  19. ********************************************************************************
  20. **
  21. ** \note The following LINT statements have been suppressed:
  22. **
  23. ** - Warning 438: Last value assigned to variable not used.
  24. ** - Warning 586: function 'mktime' is deprecated. [MISRA 2004 Rule 20.12]
  25. ** - Note 961: Violates MISRA 2004 Advisory Rule 19.7, Function-like macro
  26. ** defined
  27. *****************************************************************************
  28. */
  29. //**************************************************************************
  30. //**************************************************************************
  31. //** Standard includes
  32. //**************************************************************************
  33. //**************************************************************************
  34. #include <stdio.h>
  35. #include <string.h>
  36. #include <sys/time.h>
  37. #include <time.h>
  38. #include "internal.h"
  39. #include "errno.h"
  40. //**************************************************************************
  41. //**************************************************************************
  42. //** FAPI includes
  43. //**************************************************************************
  44. //**************************************************************************
  45. //**************************************************************************
  46. //**************************************************************************
  47. //** Defines and Macros
  48. //**************************************************************************
  49. //**************************************************************************
  50. /*lint -save -e(961) */
  51. #define IS_HIGH_BIT_SET(val) (((1LL << ((sizeof(val) * 8) - 1)) & val) != 0)
  52. /*lint -restore */
  53. //**************************************************************************
  54. //**************************************************************************
  55. //** Global Data
  56. //**************************************************************************
  57. //**************************************************************************
  58. static struct tm _localtime_tm;
  59. //******************************************************************************
  60. //******************************************************************************
  61. //** Local Functions Declaration
  62. //******************************************************************************
  63. //******************************************************************************
  64. int _is_dst(time_t t);
  65. //******************************************************************************
  66. //******************************************************************************
  67. //** API Functions
  68. //******************************************************************************
  69. //******************************************************************************
  70. /*
  71. ********************************************************************************
  72. ** \brief Retarget implementation of the stdc library function.
  73. **
  74. ** This is the standard C library gmtime() function from time.h.
  75. **
  76. ** The localtime() function shall convert the time in seconds since the epoch
  77. ** pointed to by timer into a broken-down time, expressed as a local time.
  78. ** The function corrects for the timezone and any seasonal time adjustments.
  79. ** Local timezone information is used as though localtime() calls tzset().
  80. **
  81. ** The relationship between a time in seconds since the Epoch used as an
  82. ** argument to localtime() and the tm structure (defined in the <time.h> header) is
  83. ** that the result shall be as specified in the expression given in the
  84. ** definition of seconds since the Epoch (see the Base Definitions volume of
  85. ** IEEE Std 1003.1-2001, Section 4.14, Seconds Since the Epoch), where the names
  86. ** in the structure and in the expression correspond.
  87. **
  88. ** The asctime(), ctime(), gmtime(), and localtime() functions shall return
  89. ** values in one of two static objects: a broken-down time structure and an
  90. ** array of type char. Execution of any of the functions may overwrite the
  91. ** information returned in either of these objects by any of the other
  92. ** functions.
  93. **
  94. ** \param timer Pointer to time in seconds since the epoch (00:00:00 UTC on
  95. ** 1 January 1970)
  96. **
  97. ** \return Upon successful completion, the localtime() function shall return a
  98. ** pointer to the broken-down time structure. If an error is detected,
  99. ** localtime() shall return a null pointer and set errno to indicate the error.
  100. ** ERRORS:
  101. ** - EOVERFLOW The result cannot be represented.
  102. ********************************************************************************
  103. */
  104. struct tm * localtime_r(const time_t *timer,struct tm * tmp)
  105. {
  106. struct tm *tm = tmp;
  107. uint32_t cpu_flags;
  108. /* check parameter validity */
  109. if (timer == NULL) {
  110. return (NULL);
  111. }
  112. /* check parameter validity */
  113. if (tm == NULL) {
  114. return (NULL);
  115. }
  116. /* irrespective of values sign representation, high bit set in time_t leads
  117. to an invalid (overflow) result */
  118. if (IS_HIGH_BIT_SET(*timer)) {
  119. /*lint -e{48,63} */
  120. errno = EOVERFLOW;
  121. return (NULL);
  122. }
  123. /* update time zone values based on environment variable TZ */
  124. tzset();
  125. //////////////////////////////////
  126. cpu_flags = st_enter_crit_func();
  127. //////////////////////////////////
  128. /* reset local time structure */
  129. memset(tm, 0x0, sizeof(struct tm));
  130. /* fill up time based on epoch using given seconds */
  131. tm->tm_year = 70;
  132. tm->tm_mday = 1;
  133. tm->tm_sec = (int) *timer - (int) _timezone; /* ignore DST offset first */
  134. tm->tm_isdst = _is_dst((time_t) tm->tm_sec);
  135. if (tm->tm_isdst) { /* do DST correction */
  136. tm->tm_sec -= (int) _daylight;
  137. }
  138. /* check if overflow has happened */
  139. /* irrespective of values sign representation, high bit set leads to an
  140. invalid (overflow) result */
  141. if (IS_HIGH_BIT_SET(tm->tm_sec)) {
  142. /*lint -e{48,63} */
  143. errno = EOVERFLOW;
  144. return (NULL);
  145. }
  146. /* normalize data */
  147. /*lint -e(586) */
  148. mktime(tm);
  149. //////////////////////////////
  150. st_exit_crit_func(cpu_flags);
  151. //////////////////////////////
  152. return (tm);
  153. }
  154. //******************************************************************************
  155. //******************************************************************************
  156. //** Local Functions
  157. //******************************************************************************
  158. //******************************************************************************
  159. /*
  160. ********************************************************************************
  161. ** \brief Determines if the daylight savings time should be applied.
  162. **
  163. ** This function should normally implement the various DST rules applied to
  164. ** different timezones, which would imply extensive calculation.
  165. **
  166. ** \attention The current implementation is very limited, simply informing if
  167. ** the DST is activated in the TZ variable.
  168. ** This means this implementation only works correct if the current time zone
  169. ** value is updated accordingly.
  170. **
  171. ** \param now defines the current timestamp, where DST is checked to be applied.
  172. **
  173. ** \return
  174. ** - 1, if actual time stamp is in DST range
  175. ** - 0, otherwise
  176. ********************************************************************************
  177. */
  178. /*lint -e{438} */
  179. int _is_dst(time_t now)
  180. {
  181. now = now;
  182. if (!_daylight) {
  183. return (0);
  184. }
  185. return (1);
  186. }
  187. struct tm * localtime(const time_t *timer)
  188. {
  189. return localtime_r(timer,&_localtime_tm);
  190. }