88 * 2019-08-21 zhangjun copy from minilibc
99 * 2020-09-07 Meco Man combine gcc armcc iccarm
1010 * 2021-02-05 Meco Man add timegm()
11+ * 2021-02-07 Meco Man fixed gettimeofday()
12+ * 2021-02-08 Meco Man add settimeofday() stime()
13+ * 2021-02-10 Meco Man add ctime_r() and re-implement ctime()
14+ * 2021-02-11 Meco Man fix bug #3183 - align days[] and months[] to 4 bytes
15+ * add difftime()
16+ * 2021-02-12 Meco Man add errno
1117 */
1218
1319#include <sys/time.h>
1622#include <rtdevice.h>
1723#endif
1824
19-
20- #if !defined (__IAR_SYSTEMS_ICC__ )
21-
2225/* seconds per day */
2326#define SPD 24*60*60
2427
@@ -39,8 +42,9 @@ const short __spm[13] =
3942 (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 ),
4043 (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 ),
4144};
42- static const char days [] = "Sun Mon Tue Wed Thu Fri Sat " ;
43- static const char months [] = "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec " ;
45+
46+ ALIGN (4 ) static const char days [] = "Sun Mon Tue Wed Thu Fri Sat " ;
47+ ALIGN (4 ) static const char months [] = "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec " ;
4448
4549static int __isleap (int year )
4650{
@@ -89,6 +93,8 @@ struct tm *gmtime_r(const time_t *timep, struct tm *r)
8993 ;
9094 r -> tm_mon = i ;
9195 r -> tm_mday += work - __spm [i ];
96+
97+ r -> tm_isdst = 0 ;
9298 return r ;
9399}
94100
@@ -102,10 +108,10 @@ struct tm* gmtime(const time_t* t)
102108struct tm * localtime_r (const time_t * t , struct tm * r )
103109{
104110 time_t local_tz ;
105- int timezone ;
111+ int utc_plus ;
106112
107- timezone = 0 * 3600 * 8 ; /* GTM: UTC+0 */
108- local_tz = * t + timezone ;
113+ utc_plus = 0 ; /* GTM: UTC+0 */
114+ local_tz = * t + utc_plus * 3600 ;
109115 return gmtime_r (& local_tz , r );
110116}
111117
@@ -148,44 +154,45 @@ char* asctime(const struct tm *timeptr)
148154 return asctime_r (timeptr , buf );
149155}
150156
151- char * ctime (const time_t * timep )
157+ char * ctime_r (const time_t * tim_p , char * result )
152158{
153- return asctime (localtime (timep ));
159+ struct tm tm ;
160+ return asctime_r (localtime_r (tim_p , & tm ), result );
154161}
155162
156- #endif /* __IAR_SYSTEMS_ICC__ */
163+ char * ctime (const time_t * tim_p )
164+ {
165+ return asctime (localtime (tim_p ));
166+ }
167+
168+ double difftime (time_t tim1 , time_t tim2 )
169+ {
170+ return (double )(tim1 - tim2 );
171+ }
157172
158173/**
159174 * Returns the current time.
160175 *
161176 * @param time_t * t the timestamp pointer, if not used, keep NULL.
162177 *
163- * @return time_t return timestamp current.
178+ * @return The value ((time_t)-1) is returned if the calendar time is not available.
179+ * If timer is not a NULL pointer, the return value is also stored in timer.
164180 *
165181 */
166- #if defined (__IAR_SYSTEMS_ICC__ ) && (__VER__ ) >= 6020000 /* for IAR 6.2 later Compiler */
167- #pragma module_name = "?time"
168- #if _DLIB_TIME_USES_64
169- time_t __time64 (time_t * t )
170- #else
171- time_t __time32 (time_t * t )
172- #endif
173- #else /* Keil & GCC */
174- time_t time (time_t * t )
175- #endif
182+ RT_WEAK time_t time (time_t * t )
176183{
177- time_t time_now = 0 ;
184+ time_t time_now = (( time_t ) - 1 ); /* default is not available */
178185
179186#ifdef RT_USING_RTC
180187 static rt_device_t device = RT_NULL ;
181188
182- /* optimization: find rtc device only first. */
189+ /* optimization: find rtc device only first */
183190 if (device == RT_NULL )
184191 {
185192 device = rt_device_find ("rtc" );
186193 }
187194
188- /* read timestamp from RTC device. */
195+ /* read timestamp from RTC device */
189196 if (device != RT_NULL )
190197 {
191198 if (rt_device_open (device , 0 ) == RT_EOK )
@@ -202,6 +209,11 @@ time_t time(time_t *t)
202209 * t = time_now ;
203210 }
204211
212+ if (time_now == (time_t )- 1 )
213+ {
214+ errno = ENOSYS ;
215+ }
216+
205217 return time_now ;
206218}
207219
@@ -210,26 +222,29 @@ RT_WEAK clock_t clock(void)
210222 return rt_tick_get ();
211223}
212224
213- /* TODO: timezone */
214- int gettimeofday (struct timeval * tp , struct timezone * tz )
225+ int stime (const time_t * t )
215226{
216- time_t time = 0 ;
217- #ifdef RT_USING_DEVICE
227+ #ifdef RT_USING_RTC
218228 rt_device_t device ;
229+
230+ /* read timestamp from RTC device. */
219231 device = rt_device_find ("rtc" );
220- RT_ASSERT (device != RT_NULL );
221- rt_device_control (device , RT_DEVICE_CTRL_RTC_GET_TIME , & time );
222- if (tp != RT_NULL )
232+ if (rt_device_open (device , 0 ) == RT_EOK )
223233 {
224- tp -> tv_sec = time ;
225- tp -> tv_usec = 0 ;
234+ rt_device_control ( device , RT_DEVICE_CTRL_RTC_SET_TIME , ( void * ) t ) ;
235+ rt_device_close ( device ) ;
226236 }
227- #else
228- tv -> tv_sec = 0 ;
229- tv -> tv_usec = 0 ;
230- #endif
237+ else
238+ {
239+ errno = ENOSYS ;
240+ return -1 ;
241+ }
242+ return 0 ;
231243
232- return time ;
244+ #else
245+ errno = ENOSYS ;
246+ return -1 ;
247+ #endif /* RT_USING_RTC */
233248}
234249
235250time_t timegm (struct tm * const t )
@@ -305,3 +320,35 @@ time_t timegm(struct tm * const t)
305320 i = 60 ;
306321 return ((day + t -> tm_hour ) * i + t -> tm_min ) * i + t -> tm_sec ;
307322}
323+
324+ /* TODO: timezone */
325+ int gettimeofday (struct timeval * tv , struct timezone * tz )
326+ {
327+ time_t t = time (RT_NULL );
328+
329+ if (tv != RT_NULL && t != (time_t )- 1 )
330+ {
331+ tv -> tv_sec = t ;
332+ tv -> tv_usec = 0 ;
333+ return 0 ;
334+ }
335+ else
336+ {
337+ errno = ENOSYS ;
338+ return -1 ;
339+ }
340+ }
341+
342+ /* TODO: timezone */
343+ int settimeofday (const struct timeval * tv , const struct timezone * tz )
344+ {
345+ if (tv != RT_NULL )
346+ {
347+ return stime ((const time_t * )& tv -> tv_sec );
348+ }
349+ else
350+ {
351+ errno = ENOSYS ;
352+ return -1 ;
353+ }
354+ }
0 commit comments