]> git.feebdaed.xyz Git - 0xmirror/SOEM.git/commitdiff
Add OSAL functions for monotonic time
authorHans-Erik Floryd <hans-erik.floryd@rt-labs.com>
Mon, 23 Jun 2025 12:06:36 +0000 (14:06 +0200)
committerHans-Erik Floryd <hans-erik.floryd@rt-labs.com>
Thu, 10 Jul 2025 08:23:07 +0000 (10:23 +0200)
This commit adds osal_get_monotonic_time() and
osal_monotonic_sleep(). These functions are designed to facilitate
synchronization with DC time, which can achieve nanosecond precision.

To support this functionality, the ec_timet structure has been
refactored to hold time values in nanoseconds, eliminating the need to
maintain separate time representations.

Change-Id: I039a006ccdb21ba35c437ab76e44e5153c711998

15 files changed:
cmake/Windows.cmake
osal/linux/osal.c
osal/linux/osal_defs.h
osal/osal.h
osal/rtk/osal.c
osal/rtk/osal_defs.h
osal/win32/osal.c
osal/win32/osal_defs.h
osal/win32/osal_win32.h [deleted file]
oshw/win32/nicdrv.c
samples/eepromtool/eepromtool.c
samples/firm_update/firm_update.c
samples/simple_ng/simple_ng.c
src/ec_dc.c
src/ec_print.c

index ac628c0e0dd3a68680fd88b90043bc43df59e74a..874424d6fb335de7b3a3cc8b2ec034f5f901db06 100644 (file)
@@ -17,6 +17,18 @@ target_include_directories(soem PUBLIC
   $<INSTALL_INTERFACE:include/soem>
 )
 
+target_compile_options(soem PUBLIC
+  $<$<C_COMPILER_ID:GNU>:-std=c11>
+)
+
+target_compile_definitions(soem PUBLIC
+  $<$<C_COMPILER_ID:GNU>:_UCRT>
+)
+
+target_link_libraries(soem PUBLIC
+  $<$<C_COMPILER_ID:GNU>:ucrt>
+)
+
 foreach(target IN ITEMS
     soem
     coetest
index 0cad7a42c41c517fe2b81b11cb1b84df023243ef..72e546845878f0d1a9059b6fdb1b942886fbf21b 100644 (file)
@@ -3,93 +3,70 @@
  * license. See the file LICENSE.md distributed with this software for
  * full license information.
  */
-
-#include <time.h>
-#include <sys/time.h>
-#include <unistd.h>
+#include <osal.h>
 #include <stdlib.h>
 #include <string.h>
-#include <osal.h>
 
-#define USECS_PER_SEC 1000000
-
-int osal_usleep(uint32 usec)
+/* Returns time from some unspecified moment in past,
+ * strictly increasing, used for time intervals measurement. */
+void osal_get_monotonic_time(ec_timet *ts)
 {
-   struct timespec ts;
-   ts.tv_sec = usec / USECS_PER_SEC;
-   ts.tv_nsec = (usec % USECS_PER_SEC) * 1000;
-   /* usleep is deprecated, use nanosleep instead */
-   return nanosleep(&ts, NULL);
+   /* Use clock_gettime to prevent possible live-lock.
+    * Gettimeofday uses CLOCK_REALTIME that can get NTP timeadjust.
+    * If this function preempts timeadjust and it uses vpage it live-locks.
+    * Also when using XENOMAI, only clock_gettime is RT safe */
+   clock_gettime(CLOCK_MONOTONIC, ts);
 }
 
 ec_timet osal_current_time(void)
 {
-   struct timespec current_time;
-   ec_timet return_value;
-
-   clock_gettime(CLOCK_REALTIME, &current_time);
-   return_value.sec = current_time.tv_sec;
-   return_value.usec = current_time.tv_nsec / 1000;
+   struct timespec ts;
 
-   return return_value;
+   clock_gettime(CLOCK_REALTIME, &ts);
+   return ts;
 }
 
 void osal_time_diff(ec_timet *start, ec_timet *end, ec_timet *diff)
 {
-   if (end->usec < start->usec)
-   {
-      diff->sec = end->sec - start->sec - 1;
-      diff->usec = end->usec + 1000000 - start->usec;
-   }
-   else
-   {
-      diff->sec = end->sec - start->sec;
-      diff->usec = end->usec - start->usec;
-   }
+   osal_timespecsub(end, start, diff);
 }
 
-/* Returns time from some unspecified moment in past,
- * strictly increasing, used for time intervals measurement. */
-static void osal_getrelativetime(struct timeval *tv)
+void osal_timer_start(osal_timert *self, uint32 timeout_usec)
 {
-   struct timespec ts;
+   struct timespec start_time;
+   struct timespec timeout;
 
-   /* Use clock_gettime to prevent possible live-lock.
-    * Gettimeofday uses CLOCK_REALTIME that can get NTP timeadjust.
-    * If this function preempts timeadjust and it uses vpage it live-locks.
-    * Also when using XENOMAI, only clock_gettime is RT safe */
-   clock_gettime(CLOCK_MONOTONIC, &ts);
-   tv->tv_sec = ts.tv_sec;
-   tv->tv_usec = ts.tv_nsec / 1000;
+   osal_get_monotonic_time(&start_time);
+   osal_timespec_from_usec(timeout_usec, &timeout);
+   osal_timespecadd(&start_time, &timeout, &self->stop_time);
 }
 
-void osal_timer_start(osal_timert *self, uint32 timeout_usec)
+boolean osal_timer_is_expired(osal_timert *self)
 {
-   struct timeval start_time;
-   struct timeval timeout;
-   struct timeval stop_time;
+   struct timespec current_time;
+   int is_not_yet_expired;
 
-   osal_getrelativetime(&start_time);
-   timeout.tv_sec = timeout_usec / USECS_PER_SEC;
-   timeout.tv_usec = timeout_usec % USECS_PER_SEC;
-   timeradd(&start_time, &timeout, &stop_time);
+   osal_get_monotonic_time(&current_time);
+   is_not_yet_expired = osal_timespeccmp(&current_time, &self->stop_time, <);
 
-   self->stop_time.sec = stop_time.tv_sec;
-   self->stop_time.usec = stop_time.tv_usec;
+   return is_not_yet_expired == FALSE;
 }
 
-boolean osal_timer_is_expired(osal_timert *self)
+int osal_usleep(uint32 usec)
 {
-   struct timeval current_time;
-   struct timeval stop_time;
-   int is_not_yet_expired;
+   struct timespec ts;
+   int result;
 
-   osal_getrelativetime(&current_time);
-   stop_time.tv_sec = self->stop_time.sec;
-   stop_time.tv_usec = self->stop_time.usec;
-   is_not_yet_expired = timercmp(&current_time, &stop_time, <);
+   osal_timespec_from_usec(usec, &ts);
+   result = clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL);
+   return result == 0 ? 0 : -1;
+}
 
-   return is_not_yet_expired == FALSE;
+int osal_monotonic_sleep(ec_timet *ts)
+{
+   int result;
+   result = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, ts, NULL);
+   return result == 0 ? 0 : -1;
 }
 
 void *osal_malloc(size_t size)
index 414ff40bcc35c3234dafbcc2c01ff17237e85e73..90269ac9848041e1e9290cb9196817d0fa4701f3 100644 (file)
@@ -11,6 +11,9 @@
 extern "C" {
 #endif
 
+#include <pthread.h>
+#include <sys/time.h>
+
 // define if debug printf is needed
 #ifdef EC_DEBUG
 #define EC_PRINT printf
@@ -27,7 +30,8 @@ extern "C" {
 #define PACKED_END
 #endif
 
-#include <pthread.h>
+#define ec_timet            struct timespec
+
 #define OSAL_THREAD_HANDLE  pthread_t *
 #define OSAL_THREAD_FUNC    void
 #define OSAL_THREAD_FUNC_RT void
index b95a2f7b570ebc6fb95d774d9dd9d5f7fed27fcf..b970acdd4aa5970e2f576555a7735a2f87af6139 100644 (file)
@@ -34,17 +34,16 @@ typedef uint64_t uint64;
 typedef float float32;
 typedef double float64;
 
-typedef struct
-{
-   uint32 sec;  /*< Seconds elapsed since the Epoch (Jan 1, 1970) */
-   uint32 usec; /*< Microseconds elapsed since last second boundary */
-} ec_timet;
-
 typedef struct osal_timer
 {
    ec_timet stop_time;
 } osal_timert;
 
+/* Returns time from some unspecified moment in past,
+ * strictly increasing, used for time intervals measurement. */
+void osal_get_monotonic_time(ec_timet *tv);
+int osal_monotonic_sleep(ec_timet *ts);
+
 void osal_timer_start(osal_timert *self, uint32 timeout_us);
 boolean osal_timer_is_expired(osal_timert *self);
 int osal_usleep(uint32 usec);
@@ -59,6 +58,50 @@ void osal_mutex_destroy(void *mutex);
 void osal_mutex_lock(void *mutex);
 void osal_mutex_unlock(void *mutex);
 
+#ifndef osal_timespec_from_usec
+#define osal_timespec_from_usec(usec, result)      \
+   do                                              \
+   {                                               \
+      (result)->tv_sec = usec / 1000000;           \
+      (result)->tv_nsec = (usec % 1000000) * 1000; \
+   } while (0)
+#endif
+
+#ifndef osal_timespeccmp
+#define osal_timespeccmp(a, b, CMP)      \
+   (((a)->tv_sec == (b)->tv_sec)         \
+        ? ((a)->tv_nsec CMP(b)->tv_nsec) \
+        : ((a)->tv_sec CMP(b)->tv_sec))
+#endif
+
+#ifndef osal_timespecadd
+#define osal_timespecadd(a, b, result)                 \
+   do                                                  \
+   {                                                   \
+      (result)->tv_sec = (a)->tv_sec + (b)->tv_sec;    \
+      (result)->tv_nsec = (a)->tv_nsec + (b)->tv_nsec; \
+      if ((result)->tv_nsec >= 1000000000)             \
+      {                                                \
+         ++(result)->tv_sec;                           \
+         (result)->tv_nsec -= 1000000000;              \
+      }                                                \
+   } while (0)
+#endif
+
+#ifndef osal_timespecsub
+#define osal_timespecsub(a, b, result)                 \
+   do                                                  \
+   {                                                   \
+      (result)->tv_sec = (a)->tv_sec - (b)->tv_sec;    \
+      (result)->tv_nsec = (a)->tv_nsec - (b)->tv_nsec; \
+      if ((result)->tv_nsec < 0)                       \
+      {                                                \
+         --(result)->tv_sec;                           \
+         (result)->tv_nsec += 1000000000;              \
+      }                                                \
+   } while (0)
+#endif
+
 #ifdef __cplusplus
 }
 #endif
index bd833b24781ddebd31a92c4b6c63ec0592f73321..784edc81a9ed3f576823e831c7bf3aa218865710 100644 (file)
@@ -6,93 +6,56 @@
 
 #include <osal.h>
 #include <kern/kern.h>
-#include <time.h>
-#include <sys/time.h>
-#include <config.h>
 
-#define USECS_PER_SEC  1000000
-#define USECS_PER_TICK (USECS_PER_SEC / CFG_TICKS_PER_SECOND)
-
-int gettimeofday(struct timeval *tp, void *tzp)
+void osal_get_monotonic_time(ec_timet *tv)
 {
    tick_t tick = tick_get();
-   tick_t ticks_left;
-
-   ASSERT(tp != NULL);
-
-   tp->tv_sec = tick / CFG_TICKS_PER_SECOND;
-
-   ticks_left = tick % CFG_TICKS_PER_SECOND;
-   tp->tv_usec = ticks_left * USECS_PER_TICK;
-   ASSERT(tp->tv_usec < USECS_PER_SEC);
+   uint64_t usec = (uint64_t)(tick_to_ms(tick)) * 1000;
 
-   return 0;
-}
-
-int osal_usleep(uint32 usec)
-{
-   tick_t ticks = (usec / USECS_PER_TICK) + 1;
-   task_delay(ticks);
-   return 0;
-}
-
-int osal_gettimeofday(struct timeval *tv, struct timezone *tz)
-{
-   return gettimeofday(tv, tz);
+   osal_timespec_from_usec(usec, tv);
 }
 
 ec_timet osal_current_time(void)
 {
-   struct timeval current_time;
-   ec_timet return_value;
+   struct timeval tv;
+   struct timespec ts;
 
-   gettimeofday(&current_time, 0);
-   return_value.sec = current_time.tv_sec;
-   return_value.usec = current_time.tv_usec;
-   return return_value;
+   gettimeofday(&tv, NULL);
+   TIMEVAL_TO_TIMESPEC(&tv, &ts);
+   return ts;
 }
 
 void osal_time_diff(ec_timet *start, ec_timet *end, ec_timet *diff)
 {
-   if (end->usec < start->usec)
-   {
-      diff->sec = end->sec - start->sec - 1;
-      diff->usec = end->usec + 1000000 - start->usec;
-   }
-   else
-   {
-      diff->sec = end->sec - start->sec;
-      diff->usec = end->usec - start->usec;
-   }
+   osal_timespecsub(end, start, diff);
 }
 
 void osal_timer_start(osal_timert *self, uint32 timeout_usec)
 {
-   struct timeval start_time;
-   struct timeval timeout;
-   struct timeval stop_time;
-
-   gettimeofday(&start_time, 0);
-   timeout.tv_sec = timeout_usec / USECS_PER_SEC;
-   timeout.tv_usec = timeout_usec % USECS_PER_SEC;
-   timeradd(&start_time, &timeout, &stop_time);
+   struct timespec start_time;
+   struct timespec timeout;
 
-   self->stop_time.sec = stop_time.tv_sec;
-   self->stop_time.usec = stop_time.tv_usec;
+   osal_get_monotonic_time(&start_time);
+   osal_timespec_from_usec(timeout_usec, &timeout);
+   osal_timespecadd(&start_time, &timeout, &self->stop_time);
 }
 
 boolean osal_timer_is_expired(osal_timert *self)
 {
-   struct timeval current_time;
-   struct timeval stop_time;
+   struct timespec current_time;
    int is_not_yet_expired;
 
-   gettimeofday(&current_time, 0);
-   stop_time.tv_sec = self->stop_time.sec;
-   stop_time.tv_usec = self->stop_time.usec;
-   is_not_yet_expired = timercmp(&current_time, &stop_time, <);
+   osal_get_monotonic_time(&current_time);
+   is_not_yet_expired = osal_timespeccmp(&current_time, &self->stop_time, <);
 
-   return is_not_yet_expired == false;
+   return is_not_yet_expired == FALSE;
+}
+
+int osal_usleep(uint32 usec)
+{
+   tick_t ticks = tick_from_ms(usec / 1000) + 1;
+   task_delay(ticks);
+   return 0;
 }
 
 void *osal_malloc(size_t size)
index 47763ec45775aff04c0b4011b82084b5cc73bfe9..720813d03e661a575402fbadc4a0e80ef4d9582f 100644 (file)
@@ -11,6 +11,8 @@
 extern "C" {
 #endif
 
+#include <sys/time.h>
+
 // define if debug printf is needed
 #ifdef EC_DEBUG
 #define EC_PRINT printf
@@ -27,6 +29,8 @@ extern "C" {
 #define PACKED_END
 #endif
 
+#define ec_timet            struct timespec
+
 #define OSAL_THREAD_HANDLE  task_t *
 #define OSAL_THREAD_FUNC    void
 #define OSAL_THREAD_FUNC_RT void
index a0c01ee7ecd14ceae3e785beb81d3283d55f0318..3297aa6edd03b258cbf40ee857953800ab97f750 100644 (file)
  * full license information.
  */
 
-#include <winsock2.h>
 #include <osal.h>
-#include "osal_win32.h"
+#include <stdlib.h>
+#include <inttypes.h>
+#include <timeapi.h>
 
-static int64_t sysfrequency;
-static double qpc2usec;
+static LARGE_INTEGER sysfrequency;
 
-#define USECS_PER_SEC 1000000
-
-static int osal_getrelativetime(struct timeval *tv, struct timezone *tz)
+void osal_get_monotonic_time(ec_timet *ts)
 {
-   int64_t wintime, usecs;
-   (void)tz;
-   if (!sysfrequency)
+   LARGE_INTEGER wintime;
+   uint64_t sec;
+   uint64_t nsec;
+
+   if (!sysfrequency.QuadPart)
    {
       timeBeginPeriod(1);
-      QueryPerformanceFrequency((LARGE_INTEGER *)&sysfrequency);
-      qpc2usec = 1000000.0 / sysfrequency;
+      QueryPerformanceFrequency(&sysfrequency);
    }
-   QueryPerformanceCounter((LARGE_INTEGER *)&wintime);
-   usecs = (int64_t)((double)wintime * qpc2usec);
-   tv->tv_sec = (long)(usecs / 1000000);
-   tv->tv_usec = (long)(usecs - (tv->tv_sec * 1000000));
 
-   return 1;
-}
+   QueryPerformanceCounter(&wintime);
 
-int osal_gettimeofday(struct timeval *tv, struct timezone *tz)
-{
-   FILETIME system_time;
-   int64 system_time64, usecs;
-   (void)tz;
-   /* The offset variable is required to switch from Windows epoch (January 1, 1601) to
-    * Unix epoch (January 1, 1970). Number of days between both epochs: 134.774
-    *
-    * The time returned by GetSystemTimeAsFileTime() changes in 100 ns steps, so the
-    * following factors are required for the conversion from days to 100 ns steps:
-    *
-    * 86.400 seconds per day; 1.000.000 microseconds per second; 10 * 100 ns per microsecond
-    */
-   int64 offset = -134774LL * 86400LL * 1000000LL * 10LL;
-
-   GetSystemTimeAsFileTime(&system_time);
-
-   system_time64 = ((int64)(system_time.dwHighDateTime) << 32) + (int64)system_time.dwLowDateTime;
-   system_time64 += offset;
-   usecs = system_time64 / 10;
-
-   tv->tv_sec = (long)(usecs / 1000000);
-   tv->tv_usec = (long)(usecs - (tv->tv_sec * 1000000));
+   /* Compute seconds */
+   sec = wintime.QuadPart / sysfrequency.QuadPart;
+   wintime.QuadPart = wintime.QuadPart - sec * sysfrequency.QuadPart;
 
-   return 1;
+   /* Compute nanoseconds. Multiplying first acts as a guard against
+      potential loss of precision during the calculation. */
+   nsec = wintime.QuadPart * 1000000000;
+   nsec = nsec / sysfrequency.QuadPart;
+
+   ts->tv_sec = sec;
+   ts->tv_nsec = (uint32_t)nsec;
 }
 
 ec_timet osal_current_time(void)
 {
-   struct timeval current_time;
-   ec_timet return_value;
-
-   osal_gettimeofday(&current_time, 0);
-   return_value.sec = current_time.tv_sec;
-   return_value.usec = current_time.tv_usec;
-   return return_value;
+   struct timespec ts;
+   timespec_get(&ts, TIME_UTC);
+   return ts;
 }
 
 void osal_time_diff(ec_timet *start, ec_timet *end, ec_timet *diff)
 {
-   if (end->usec < start->usec)
-   {
-      diff->sec = end->sec - start->sec - 1;
-      diff->usec = end->usec + 1000000 - start->usec;
-   }
-   else
-   {
-      diff->sec = end->sec - start->sec;
-      diff->usec = end->usec - start->usec;
-   }
+   osal_timespecsub(end, start, diff);
 }
 
 void osal_timer_start(osal_timert *self, uint32 timeout_usec)
 {
-   struct timeval start_time;
-   struct timeval timeout;
-   struct timeval stop_time;
-
-   osal_getrelativetime(&start_time, 0);
-   timeout.tv_sec = timeout_usec / USECS_PER_SEC;
-   timeout.tv_usec = timeout_usec % USECS_PER_SEC;
-   timeradd(&start_time, &timeout, &stop_time);
+   struct timespec start_time;
+   struct timespec timeout;
 
-   self->stop_time.sec = stop_time.tv_sec;
-   self->stop_time.usec = stop_time.tv_usec;
+   osal_get_monotonic_time(&start_time);
+   osal_timespec_from_usec(timeout_usec, &timeout);
+   osal_timespecadd(&start_time, &timeout, &self->stop_time);
 }
 
 boolean osal_timer_is_expired(osal_timert *self)
 {
-   struct timeval current_time;
-   struct timeval stop_time;
+   struct timespec current_time;
    int is_not_yet_expired;
 
-   osal_getrelativetime(&current_time, 0);
-   stop_time.tv_sec = self->stop_time.sec;
-   stop_time.tv_usec = self->stop_time.usec;
-   is_not_yet_expired = timercmp(&current_time, &stop_time, <);
+   osal_get_monotonic_time(&current_time);
+   is_not_yet_expired = osal_timespeccmp(&current_time, &self->stop_time, <);
 
    return is_not_yet_expired == FALSE;
 }
 
 int osal_usleep(uint32 usec)
 {
-   osal_timert qtime;
-   osal_timer_start(&qtime, usec);
-   if (usec >= 1000)
+   struct timespec wakeup;
+   struct timespec timeout;
+
+   osal_get_monotonic_time(&wakeup);
+   osal_timespec_from_usec(usec, &timeout);
+   osal_timespecadd(&wakeup, &timeout, &wakeup);
+   osal_monotonic_sleep(&wakeup);
+   return 1;
+}
+
+/**
+ * @brief Suspends the execution of the calling thread until a
+ * specified absolute time.
+ *
+ * @param ts Pointer to a struct that specifies the
+ * absolute wakeup time in milliseconds.
+ * @return 0 on success, or a negative value on error.
+ */
+int osal_monotonic_sleep(ec_timet *ts)
+{
+   uint64_t millis;
+   struct timespec now;
+   struct timespec delay;
+
+   osal_get_monotonic_time(&now);
+
+   /* Delay already expired? */
+   if (!osal_timespeccmp(&now, ts, <))
+      return 0;
+
+   /* Sleep for whole milliseconds */
+   osal_timespecsub(ts, &now, &delay);
+   millis = delay.tv_sec * 1000 + delay.tv_nsec / 1000000;
+   if (millis > 0)
    {
-      SleepEx(usec / 1000, FALSE);
+      SleepEx((DWORD)millis, FALSE);
    }
-   while (!osal_timer_is_expired(&qtime))
-      ;
-   return 1;
+
+   /* Busy wait for remaining time */
+   do
+   {
+      osal_get_monotonic_time(&now);
+   } while osal_timespeccmp(&now, ts, <);
+
+   return 0;
 }
 
 void *osal_malloc(size_t size)
index 30ac107a27a7ccd43d5122afbf8021b86b2ebcce..a2164d28618e1fbafad7fff797c8a223616f0f37 100644 (file)
@@ -13,6 +13,7 @@ extern "C" {
 
 #define WIN32_LEAN_AND_MEAN // Exclude some conflicting definitions in windows header
 #include <windows.h>
+#include <time.h>
 // define if debug printf is needed
 #ifdef EC_DEBUG
 #define EC_PRINT printf
@@ -32,9 +33,10 @@ extern "C" {
 #define PACKED_BEGIN __pragma(pack(push, 1))
 #define PACKED_END   __pragma(pack(pop))
 #endif
-
 #endif
 
+#define ec_timet            struct timespec
+
 #define OSAL_THREAD_HANDLE  HANDLE
 #define OSAL_THREAD_FUNC    void
 #define OSAL_THREAD_FUNC_RT void
diff --git a/osal/win32/osal_win32.h b/osal/win32/osal_win32.h
deleted file mode 100644 (file)
index 4e665e5..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * This software is dual-licensed under GPLv3 and a commercial
- * license. See the file LICENSE.md distributed with this software for
- * full license information.
- */
-
-#ifndef _osal_win32_
-#define _osal_win32_
-
-/* Convenience macros for operations on timevals.
-   NOTE: `timercmp' does not work for >= or <=.  */
-#define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec)
-#define timeradd(a, b, result)                         \
-   do                                                  \
-   {                                                   \
-      (result)->tv_sec = (a)->tv_sec + (b)->tv_sec;    \
-      (result)->tv_usec = (a)->tv_usec + (b)->tv_usec; \
-      if ((result)->tv_usec >= 1000000)                \
-      {                                                \
-         ++(result)->tv_sec;                           \
-         (result)->tv_usec -= 1000000;                 \
-      }                                                \
-   } while (0)
-#define timersub(a, b, result)                         \
-   do                                                  \
-   {                                                   \
-      (result)->tv_sec = (a)->tv_sec - (b)->tv_sec;    \
-      (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
-      if ((result)->tv_usec < 0)                       \
-      {                                                \
-         --(result)->tv_sec;                           \
-         (result)->tv_usec += 1000000;                 \
-      }                                                \
-   } while (0)
-
-struct timezone;
-// currently the tz parameter is ignored in the win32 implmentation.
-int osal_gettimeofday(struct timeval *tv, struct timezone *tz);
-
-#endif
index d3427787cc7fefe9b128950c29ce35717b83dce5..5ac56e2128af1233f561772a24adbfd07de4caf8 100644 (file)
@@ -38,7 +38,6 @@
 #include <winsock2.h>
 #include "soem/soem.h"
 #include "nicdrv.h"
-#include "osal_win32.h"
 
 /** Redundancy modes */
 enum
index b0617b5fde9350b2289f87acc67a01b659f7c697..2b7e8080f74e87f0f98a4276b13260c75f7b4d79 100644 (file)
@@ -403,7 +403,7 @@ void eepromtool(char *ifname, int slave, int mode, char *fname)
                if (mode == MODE_READINTEL) output_intelhex(fname, esize);
                if (mode == MODE_READBIN) output_bin(fname, esize);
 
-               printf("\nTotal EEPROM read time :%ldms\n", (tdif.usec + (tdif.sec * 1000000L)) / 1000);
+               printf("\nTotal EEPROM read time :%dms\n", (int)(tdif.tv_sec * 1000 + tdif.tv_nsec / 1000000));
             }
             if ((mode == MODE_WRITEBIN) || (mode == MODE_WRITEINTEL))
             {
@@ -427,7 +427,7 @@ void eepromtool(char *ifname, int slave, int mode, char *fname)
                   tend = osal_current_time();
                   osal_time_diff(&tstart, &tend, &tdif);
 
-                  printf("\nTotal EEPROM write time :%ldms\n", (tdif.usec + (tdif.sec * 1000000L)) / 1000);
+                  printf("\nTotal EEPROM write time :%dms\n", (int)(tdif.tv_sec * 1000 + tdif.tv_nsec / 1000000));
                }
                else
                   printf("Error reading file, abort.\n");
index a696ee17ebdc52bdc8d84397a7d7ef8845b5ae4a..fec2729335d17e2c58a9376cbe69620979d78ecb 100644 (file)
@@ -15,8 +15,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <sys/time.h>
-#include <unistd.h>
 
 #include "soem/soem.h"
 
index 0bd1bf8fcd437dd5bc79b533dbbfaccc7dad7a9b..d345f3aa62d79dfe13cc85054be6eebeec7f2da5 100644 (file)
@@ -92,7 +92,7 @@ fieldbus_roundtrip(Fieldbus *fieldbus)
    wkc = ecx_receive_processdata(context, EC_TIMEOUTRET);
    end = osal_current_time();
    osal_time_diff(&start, &end, &diff);
-   fieldbus->roundtrip_time = diff.sec * 1000000 + diff.usec;
+   fieldbus->roundtrip_time = (int)(diff.tv_sec * 1000000 + diff.tv_nsec / 1000);
 
    return wkc;
 }
index 10e85cffd9638ad456fc0931570d7f656cc0fc97..92f1f562a103c6bfb3ec4916c626c4c4e8405f78 100644 (file)
@@ -267,8 +267,8 @@ boolean ecx_configdc(ecx_contextt *context)
 
    ecx_BWR(context->port, 0, ECT_REG_DCTIME0, sizeof(ht), &ht, EC_TIMEOUTRET); /* latch DCrecvTimeA of all slaves */
    mastertime = osal_current_time();
-   mastertime.sec -= 946684800UL; /* EtherCAT uses 2000-01-01 as epoch start instead of 1970-01-01 */
-   mastertime64 = (((uint64)mastertime.sec * 1000000) + (uint64)mastertime.usec) * 1000;
+   mastertime.tv_sec -= 946684800UL; /* EtherCAT uses 2000-01-01 as epoch start instead of 1970-01-01 */
+   mastertime64 = ((uint64)mastertime.tv_sec * 1000 * 1000 * 1000) + (uint64)mastertime.tv_nsec;
    for (i = 1; i <= *(context->slavecount); i++)
    {
       context->slavelist[i].consumedports = context->slavelist[i].activeports;
index a7038e55b3bc8faaf75ec3305a8c8a1fa05bd384..2f79f2d959e3a321a6e5316e34789d3d14b29275 100644 (file)
@@ -309,7 +309,7 @@ char *ec_mbxerror2string(uint16 errorcode)
 char *ecx_err2string(const ec_errort Ec)
 {
    char timestr[20];
-   sprintf(timestr, "Time:%12.3f", Ec.Time.sec + (Ec.Time.usec / 1000000.0));
+   sprintf(timestr, "Time:%12.3f", Ec.Time.tv_sec + (Ec.Time.tv_nsec / 1000000000.0));
    switch (Ec.Etype)
    {
    case EC_ERR_TYPE_SDO_ERROR: