Browse Source

add time related function.

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1090 bbd45198-f89e-11dd-88c7-29a3b14d5316
bernard.xiong 14 years ago
parent
commit
cb72c44e5a

+ 43 - 0
components/libc/newlib/clock_time.c

@@ -0,0 +1,43 @@
+#include <rtthread.h>
+
+#include <time.h>
+#include <errno.h>
+#include "libc.h"
+
+int clock_getres(clockid_t clock_id, struct timespec *res)
+{
+	if ((clock_id != CLOCK_REALTIME) || (res == RT_NULL))
+	{
+		rt_set_errno(EINVAL);
+		return -1;
+	}
+
+	res->tv_sec  = 0;
+	res->tv_nsec = NANOSECOND_PER_TICK;
+
+	return 0;
+}
+
+int clock_gettime(clockid_t clock_id, struct timespec *tp)
+{
+	if ((clock_id != CLOCK_REALTIME) || (tp == RT_NULL))
+	{
+		rt_set_errno(EINVAL);
+		return -1;
+	}
+
+	libc_get_time(tp);
+	return 0;
+}
+
+int clock_settime(clockid_t clock_id, const struct timespec *tp)
+{
+	if ((clock_id != CLOCK_REALTIME) || (tp == RT_NULL))
+	{
+		rt_set_errno(EINVAL);
+		return -1;
+	}
+
+	libc_set_time(tp);
+	return 0;
+}

+ 76 - 12
components/libc/newlib/libc.c

@@ -3,25 +3,95 @@
 #include <stdlib.h>
 #include <fcntl.h>
 #include <sys/time.h>
+#include "libc.h"
 
 struct timeval _timevalue;
 static void libc_system_time_init()
 {
-    rt_device_t device;
     time_t time;
     rt_tick_t tick;
+    rt_device_t device;
 
-    time = 0; tick = 0;
+    time = 0;
     device = rt_device_find("rtc");
     if (device != RT_NULL)
     {
+		/* get realtime seconds */
         rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &time);
     }
 
+	/* get tick */
+    tick = rt_tick_get();
+
+    _timevalue.tv_usec = MICROSECOND_PER_SECOND - (tick%RT_TICK_PER_SECOND) * MICROSECOND_PER_TICK;
+    _timevalue.tv_sec = time - tick/RT_TICK_PER_SECOND - 1;
+}
+
+int libc_get_time(struct timespec *time)
+{
+	rt_tick_t tick;
+	RT_ASSERT(time != RT_NULL);
+
+	/* get tick */
+	tick = rt_tick_get();
+
+	time->tv_sec = _timevalue.tv_sec + tick / RT_TICK_PER_SECOND;
+	time->tv_nsec = (_timevalue.tv_usec + (tick % RT_TICK_PER_SECOND) * NANOSECOND_PER_TICK) * 1000;
+
+	return 0;
+}
+
+int libc_set_time(const struct timespec *time)
+{
+	int second;
+	rt_tick_t tick;
+    rt_device_t device;
+
+	second = time->tv_sec;
+    device = rt_device_find("rtc");
+    if (device != RT_NULL)
+    {
+		/* get realtime seconds */
+        rt_device_control(device, RT_DEVICE_CTRL_RTC_SET_TIME, &second);
+    }
+	else return -1;
+
+	/* get tick */
     tick = rt_tick_get();
 
-    _timevalue.tv_sec = time;
-    _timevalue.tv_usec = (1000000UL * tick)/RT_TICK_PER_SECOND;
+	/* update timevalue */
+    _timevalue.tv_usec = MICROSECOND_PER_SECOND - (tick % RT_TICK_PER_SECOND) * MICROSECOND_PER_TICK;
+    _timevalue.tv_sec = second - tick/RT_TICK_PER_SECOND - 1;
+
+	return 0;
+}
+
+int libc_time_to_tick(const struct timespec *time)
+{
+	int tick;
+	int microsecond, second;
+
+	RT_ASSERT(time != RT_NULL);
+
+	tick = RT_WAITING_FOREVER;
+	if (time != NULL)
+	{
+		if ((time->tv_nsec/1000 - _timevalue.tv_usec) < 0)
+		{
+			microsecond = (1000000UL + time->tv_nsec/1000) - _timevalue.tv_usec;
+			second  = time->tv_sec - 1;
+		}
+		else
+		{
+			microsecond = time->tv_nsec/1000 - _timevalue.tv_usec;
+			second  = time->tv_sec;
+		}
+
+		tick = second * RT_TICK_PER_SECOND + microsecond * RT_TICK_PER_SECOND / MICROSECOND_PER_SECOND;
+		if (tick < 0) tick = 0;
+	}
+
+	return tick;
 }
 
 void libc_system_init(const char* tty_name)
@@ -39,13 +109,7 @@ void libc_system_init(const char* tty_name)
 	/* set PATH and HOME */
 	putenv("PATH=/");
 	putenv("HOME=/");
-}
-
-int libc_time_to_tick(const struct timespec *time)
-{
-	int tick;
 
-	tick = RT_WAITING_FOREVER;
-
-	return tick;
+	/* initialize system time */
+	libc_system_time_init();
 }

+ 14 - 0
components/libc/newlib/libc.h

@@ -1,7 +1,21 @@
 #ifndef __RTT_LIBC_H__
 #define __RTT_LIBC_H__
 
+#include <sys/time.h>
+
+#define MILLISECOND_PER_SECOND	1000UL
+#define MICROSECOND_PER_SECOND	1000000UL
+#define NANOSECOND_PER_SECOND	1000000000UL
+
+#define MILLISECOND_PER_TICK	(MILLISECOND_PER_SECOND / RT_TICK_PER_SECOND)
+#define MICROSECOND_PER_TICK	(MICROSECOND_PER_SECOND / RT_TICK_PER_SECOND)
+#define NANOSECOND_PER_TICK		(NANOSECOND_PER_SECOND  / RT_TICK_PER_SECOND)
+
 void libc_system_init(const char* tty_name);
+
+/* some time related function */
+int libc_set_time(const struct timespec *time);
+int libc_get_time(struct timespec *time);
 int libc_time_to_tick(const struct timespec *time);
 
 #endif

+ 14 - 0
components/libc/newlib/syscalls.c

@@ -1,5 +1,6 @@
 #include <reent.h>
 #include <sys/errno.h>
+#include <sys/time.h>
 #include <rtthread.h>
 
 /* Reentrant versions of system calls.  */
@@ -172,6 +173,19 @@ _write_r(struct _reent *ptr, int fd, const void *buf, size_t nbytes)
 int
 _gettimeofday_r(struct _reent *ptr, struct timeval *__tp, void *__tzp)
 {
+	struct timespec tp;
+
+	if (libc_get_time(&tp) == 0)
+	{
+		if (__tp != RT_NULL)
+		{
+			__tp->tv_sec  = tp.tv_sec;
+			__tp->tv_usec = tp.tv_nsec * 1000UL;
+		}
+
+		return tp.tv_sec;
+	}
+
 	/* return "not supported" */
 	ptr->_errno = ENOTSUP;
 	return -1;