From b91f6eb6d06028f840b7ffbcc01a320f8ecb283c Mon Sep 17 00:00:00 2001 From: Florian Pose <fp@igh-essen.com> Date: Fri, 24 Apr 2009 10:24:53 +0000 Subject: [PATCH] Replaced timeval by 64-bit EtherCAT time. --- TODO | 4 ++-- examples/dc_rtai/dc_rtai_sample.c | 7 +++++-- examples/dc_user/main.c | 2 +- include/ecrt.h | 20 +++++++++++++++++--- lib/master.c | 6 ++---- master/cdev.c | 2 +- master/globals.h | 7 ------- master/ioctl.h | 2 +- master/master.c | 4 ++-- 9 files changed, 31 insertions(+), 23 deletions(-) diff --git a/TODO b/TODO index 41ee54ac..42ba4707 100644 --- a/TODO +++ b/TODO @@ -12,8 +12,8 @@ Version 1.5.0: * Distributed clocks: - Delay calculation. - - User same application time offset when setting start times. - - Replace timeval by uint64 EtherCAT time. + - Use common application time offset when setting start times. + - Check 32/64 bit operations. * Fix arguments of reg_read. * Sign/Abs type for reg_ commands? * Number layout for reg_read. diff --git a/examples/dc_rtai/dc_rtai_sample.c b/examples/dc_rtai/dc_rtai_sample.c index c587302a..503cbdeb 100644 --- a/examples/dc_rtai/dc_rtai_sample.c +++ b/examples/dc_rtai/dc_rtai_sample.c @@ -220,13 +220,16 @@ void run(long data) tv.tv_usec -= 1000000; tv.tv_sec++; } - //printk(KERN_INFO PFX "tv=%u.%06u\n", (u32) tv.tv_sec, (u32) tv.tv_usec); if (sync_ref_counter) { sync_ref_counter--; } else { sync_ref_counter = 9; - ecrt_master_sync_reference_clock(master, &tv); +#if 0 + printk(KERN_INFO PFX "ref: %u %u %llu\n", + (u32) tv.tv_sec, (u32) tv.tv_usec, EC_TIMEVAL2NANO(&tv)); +#endif + ecrt_master_sync_reference_clock(master, EC_TIMEVAL2NANO(&tv)); } ecrt_master_sync_slave_clocks(master); ecrt_domain_queue(domain1); diff --git a/examples/dc_user/main.c b/examples/dc_user/main.c index 1bffa4e3..444a0abf 100644 --- a/examples/dc_user/main.c +++ b/examples/dc_user/main.c @@ -169,7 +169,7 @@ void cyclic_task() sync_ref_counter--; } else { sync_ref_counter = 9; - ecrt_master_sync_reference_clock(master, &app_time); + ecrt_master_sync_reference_clock(master, EC_TIMEVAL2NANO(&app_time)); } ecrt_master_sync_slave_clocks(master); diff --git a/include/ecrt.h b/include/ecrt.h index ac53f9e7..ed8317a9 100644 --- a/include/ecrt.h +++ b/include/ecrt.h @@ -46,7 +46,8 @@ * ecrt_slave_config_dc_sync_cycle_times() and * ecrt_slave_config_dc_sync_shift_times() to configure a slave for cyclic * operation, and ecrt_master_sync_reference_clock() and - * ecrt_master_sync_slave_clocks() for drift compensation. + * ecrt_master_sync_slave_clocks() for drift compensation. The + * EC_TIMEVAL2NANO() macro can be used for epoch time conversion. * - Changed the meaning of the negative return values of * ecrt_slave_config_reg_pdo_entry() and ecrt_slave_config_sdo*(). * - Imlemented the Vendor-specific over EtherCAT mailbox protocol. See @@ -114,6 +115,17 @@ */ #define EC_MAX_STRING_LENGTH 64 +/** Timeval to nanoseconds conversion. + * + * This macro converts a unix epoch time to EtherCAT DC time. + * + * \see ecrt_master_sync_reference_clock() + * + * \param TV Pointer to struct timeval. + */ +#define EC_TIMEVAL2NANO(TV) \ + (((TV)->tv_sec - 946684800ULL) * 1000000000ULL + (TV)->tv_usec * 1000ULL) + /****************************************************************************** * Data types *****************************************************************************/ @@ -510,11 +522,13 @@ void ecrt_master_state( /** Queues the DC reference clock drift compensation datagram for sending. * - * The reference clock will by synchronized to the \a app_time. + * The reference clock will by synchronized to the \a app_time. The time is + * defined as nanoseconds from 2000-01-01 00:00. Converting an epoch time can + * be done with the EC_TIMEVAL2NANO() macro. */ void ecrt_master_sync_reference_clock( ec_master_t *master, /**< EtherCAT master. */ - const struct timeval *app_time /**< Application time. */ + uint64_t app_time /**< Application time. */ ); /** Queues the DC clock drift compensation datagram for sending. diff --git a/lib/master.c b/lib/master.c index 298cd60f..f266f752 100644 --- a/lib/master.c +++ b/lib/master.c @@ -190,13 +190,11 @@ void ecrt_master_state(const ec_master_t *master, ec_master_state_t *state) /*****************************************************************************/ -void ecrt_master_sync_reference_clock(ec_master_t *master, - const struct timeval *app_time) +void ecrt_master_sync_reference_clock(ec_master_t *master, uint64_t app_time) { ec_ioctl_dc_t data; - data.app_time.tv_sec = app_time->tv_sec; - data.app_time.tv_usec = app_time->tv_usec; + data.app_time = app_time; if (ioctl(master->fd, EC_IOCTL_SYNC_REF, &data) == -1) { fprintf(stderr, "Failed to sync reference clock: %s\n", diff --git a/master/cdev.c b/master/cdev.c index 8fbd265c..395ccdb2 100644 --- a/master/cdev.c +++ b/master/cdev.c @@ -1647,7 +1647,7 @@ int ec_cdev_ioctl_sync_ref( return -EFAULT; spin_lock_bh(&master->internal_lock); - ecrt_master_sync_reference_clock(master, &data.app_time); + ecrt_master_sync_reference_clock(master, data.app_time); spin_unlock_bh(&master->internal_lock); return 0; } diff --git a/master/globals.h b/master/globals.h index 2daf06c6..3444f150 100644 --- a/master/globals.h +++ b/master/globals.h @@ -251,13 +251,6 @@ enum { .name = EC_STR(NAME), .owner = THIS_MODULE, .mode = S_IRUGO | S_IWUSR \ } -/** Timeval to nanoseconds conversion. - * - * \param TV Pointer to struct timeval. - */ -#define EC_TIMEVAL2NANO(TV) \ - (((TV)->tv_sec - 946684800ULL) * 1000000000ULL + (TV)->tv_usec * 1000ULL) - /*****************************************************************************/ extern char *ec_master_version_str; diff --git a/master/ioctl.h b/master/ioctl.h index fb3d3171..431fe246 100644 --- a/master/ioctl.h +++ b/master/ioctl.h @@ -389,7 +389,7 @@ typedef struct { typedef struct { // inputs - struct timeval app_time; + uint64_t app_time; } ec_ioctl_dc_t; /*****************************************************************************/ diff --git a/master/master.c b/master/master.c index e0a8384f..231b7a80 100644 --- a/master/master.c +++ b/master/master.c @@ -1651,9 +1651,9 @@ void ecrt_master_state(const ec_master_t *master, ec_master_state_t *state) /*****************************************************************************/ void ecrt_master_sync_reference_clock(ec_master_t *master, - const struct timeval *app_time) + uint64_t app_time) { - master->app_time = EC_TIMEVAL2NANO(app_time); + master->app_time = app_time; EC_WRITE_U32(master->ref_sync_datagram.data, master->app_time); ec_master_queue_datagram(master, &master->ref_sync_datagram); } -- GitLab