Browse Source

implement set_timeval

Meco Man 4 years ago
parent
commit
8e2a456d7a
3 changed files with 127 additions and 65 deletions
  1. 4 1
      components/libc/compilers/common/sys/time.h
  2. 119 60
      components/libc/compilers/common/time.c
  3. 4 4
      include/rtdef.h

+ 4 - 1
components/libc/compilers/common/sys/time.h

@@ -40,7 +40,7 @@ struct timeval {
 #endif
 #endif /* _TIMEVAL_DEFINED */
 
-#if !(defined(__GNUC__) && !defined(__ARMCC_VERSION)) && !defined (__ICCARM__) && !defined (_WIN32)
+#if !(defined(__GNUC__) && !defined(__ARMCC_VERSION)/*GCC*/) && !defined (__ICCARM__) && !defined (_WIN32)
 struct timespec {
     time_t  tv_sec;     /* seconds */
     long    tv_nsec;    /* and nanoseconds */
@@ -56,6 +56,9 @@ int stime(const time_t *t);
 time_t timegm(struct tm * const t);
 int gettimeofday(struct timeval *tv, struct timezone *tz);
 int settimeofday(const struct timeval *tv, const struct timezone *tz);
+#if defined(__ARMCC_VERSION) || defined (__ICCARM__)
+struct tm *gmtime_r(const time_t *timep, struct tm *r);
+#endif
 
 #ifdef RT_USING_POSIX
 #include <sys/types.h>

+ 119 - 60
components/libc/compilers/common/time.c

@@ -68,6 +68,104 @@ static void num2str(char *c, int i)
     c[1] = i % 10 + '0';
 }
 
+/**
+ * Get time from RTC device (without timezone)
+ * @param tv: struct timeval
+ * @return -1 failure; 1 success
+ */
+static int get_timeval(struct timeval *tv)
+{
+#ifdef RT_USING_RTC
+    static rt_device_t device = RT_NULL;
+#endif
+    rt_err_t rst = -RT_ERROR;
+
+    if (tv == RT_NULL)
+        return -1;
+
+    /* default is 0 */
+    tv->tv_sec = 0;
+    tv->tv_usec = 0;
+
+#ifdef RT_USING_RTC
+    /* optimization: find rtc device only first */
+    if (device == RT_NULL)
+    {
+        device = rt_device_find("rtc");
+    }
+
+    /* read timestamp from RTC device */
+    if (device != RT_NULL)
+    {
+        if (rt_device_open(device, 0) == RT_EOK)
+        {
+            rst = rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &tv->tv_sec);
+            rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME_US, &tv->tv_usec);
+            rt_device_close(device);
+        }
+    }
+    else
+    {
+        /* LOG_W will cause a recursive printing if ulog timestamp function is turned on */
+        rt_kprintf("Cannot find a RTC device to provide time!\r\n");
+        return -1;
+    }
+
+    return (rst < 0) ? -1 : 1;
+
+#else
+    /* LOG_W will cause a recursive printing if ulog timestamp function is turned on */
+    rt_kprintf("Cannot find a RTC device to provide time!\r\n");
+    return -1;
+#endif /* RT_USING_RTC */
+}
+
+/**
+ * Set time to RTC device (without timezone)
+ * @param tv: struct timeval
+ * @return -1 failure; 1 success
+ */
+static int set_timeval(struct timeval *tv)
+{
+    rt_err_t rst = -RT_ERROR;
+#ifdef RT_USING_RTC
+    static rt_device_t device = RT_NULL;
+#endif
+
+    if (tv == RT_NULL)
+        return -1;
+
+#ifdef RT_USING_RTC
+    /* optimization: find rtc device only first */
+    if (device == RT_NULL)
+    {
+        device = rt_device_find("rtc");
+    }
+
+    /* read timestamp from RTC device */
+    if (device != RT_NULL)
+    {
+        if (rt_device_open(device, 0) == RT_EOK)
+        {
+            rst = rt_device_control(device, RT_DEVICE_CTRL_RTC_SET_TIME, &tv->tv_sec);
+            rt_device_control(device, RT_DEVICE_CTRL_RTC_SET_TIME_US, &tv->tv_usec);
+            rt_device_close(device);
+        }
+    }
+    else
+    {
+        LOG_W("Cannot find a RTC device to provide time!");
+        return -1;
+    }
+
+    return (rst < 0) ? -1 : 1;
+
+#else
+    LOG_W("Cannot find a RTC device to provide time!");
+    return -1;
+#endif /* RT_USING_RTC */
+}
+
 struct tm *gmtime_r(const time_t *timep, struct tm *r)
 {
     time_t i;
@@ -183,49 +281,6 @@ char* ctime(const time_t *tim_p)
 }
 RTM_EXPORT(ctime);
 
-/*-1 failure; 1 success*/
-static int get_timeval(struct timeval *tv)
-{
-    if (tv == RT_NULL)
-        return -1;
-
-    /* default is not available */
-    tv->tv_sec = -1;
-    /* default is 0 */
-    tv->tv_usec = 0;
-
-#ifdef RT_USING_RTC
-    static rt_device_t device = RT_NULL;
-
-    /* optimization: find rtc device only first */
-    if (device == RT_NULL)
-    {
-        device = rt_device_find("rtc");
-    }
-
-    /* read timestamp from RTC device */
-    if (device != RT_NULL)
-    {
-        if (rt_device_open(device, 0) == RT_EOK)
-        {
-            rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &tv->tv_sec);
-            rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME_US, &tv->tv_usec);
-            rt_device_close(device);
-        }
-    }
-#endif /* RT_USING_RTC */
-
-    if (tv->tv_sec == (time_t) -1)
-    {
-        /* LOG_W will cause a recursive printing if ulog timestamp function is turned on */
-        rt_kprintf("Cannot find a RTC device to provide time!\r\n");
-        tv->tv_sec = 0;
-        return -1;
-    }
-
-    return 1;
-}
-
 /**
  * Returns the current time.
  *
@@ -239,7 +294,7 @@ RT_WEAK time_t time(time_t *t)
 {
     struct timeval now;
 
-    if(get_timeval(&now)>0)
+    if(get_timeval(&now) > 0)
     {
         if (t)
         {
@@ -263,28 +318,24 @@ RTM_EXPORT(clock);
 
 int stime(const time_t *t)
 {
-#ifdef RT_USING_RTC
-    rt_device_t device;
+    struct timeval tv;
 
-    /* read timestamp from RTC device. */
-    device = rt_device_find("rtc");
-    if (rt_device_open(device, 0) == RT_EOK)
+    if (!t)
+    {
+        errno = EFAULT;
+        return -1;
+    }
+
+    tv.tv_sec = *t;
+    if (set_timeval(&tv) > 0)
     {
-        rt_device_control(device, RT_DEVICE_CTRL_RTC_SET_TIME, (void*)t);
-        rt_device_close(device);
+        return 0;
     }
     else
     {
-        LOG_W("Cannot find a RTC device to provide time!");
         errno = EFAULT;
         return -1;
     }
-    return 0;
-#else
-    LOG_W("Cannot find a RTC device to provide time!");
-    errno = EFAULT;
-    return -1;
-#endif /* RT_USING_RTC */
 }
 RTM_EXPORT(stime);
 
@@ -366,7 +417,7 @@ RTM_EXPORT(timegm);
 /* TODO: timezone */
 int gettimeofday(struct timeval *tv, struct timezone *tz)
 {
-    if (tv != RT_NULL && get_timeval(tv)>0)
+    if (tv != RT_NULL && get_timeval(tv) > 0)
     {
         return 0;
     }
@@ -385,7 +436,15 @@ int settimeofday(const struct timeval *tv, const struct timezone *tz)
     {
         if(tv->tv_sec >= 0 && tv->tv_usec >= 0)
         {
-            return stime((const time_t *)&tv->tv_sec);
+            if(set_timeval((struct timeval *)tv) > 0)
+            {
+                return 0;
+            }
+            else
+            {
+                errno = EFAULT;
+                return -1;
+            }
         }
         else
         {

+ 4 - 4
include/rtdef.h

@@ -964,10 +964,10 @@ enum rt_device_class_type
 #define RT_DEVICE_CTRL_MTD_FORMAT       0x10            /**< format a MTD device */
 #define RT_DEVICE_CTRL_RTC_GET_TIME     0x10            /**< get second time */
 #define RT_DEVICE_CTRL_RTC_SET_TIME     0x11            /**< set second time */
-#define RT_DEVICE_CTRL_RTC_GET_ALARM    0x12            /**< get alarm */
-#define RT_DEVICE_CTRL_RTC_SET_ALARM    0x13            /**< set alarm */
-#define RT_DEVICE_CTRL_RTC_GET_TIME_US  0x14            /**< get microsecond time */
-#define RT_DEVICE_CTRL_RTC_SET_TIME_US  0x15            /**< set microsecond time */
+#define RT_DEVICE_CTRL_RTC_GET_TIME_US  0x12            /**< get microsecond time */
+#define RT_DEVICE_CTRL_RTC_SET_TIME_US  0x13            /**< set microsecond time */
+#define RT_DEVICE_CTRL_RTC_GET_ALARM    0x14            /**< get alarm */
+#define RT_DEVICE_CTRL_RTC_SET_ALARM    0x15            /**< set alarm */
 
 typedef struct rt_device *rt_device_t;