[etherlab-users] How to perform DC time synchronisation the right way?

Michael Ruder rudermi at gmx.de
Tue May 15 18:34:27 CEST 2018


Hello,

I am progressing quite well with EtherLab and am currently working on 
synchronizing outputs/movement with the Master time. We are using the 
Master 1.5.2 from the 1.5.2 branch, ec_generic driver with PREEMPT RT 
(kernel 4.14.28).

In our application, we need to be synchronized to the real time (UTC). We 
use a GPS receiver and Chrony to synchronize our PC clock to within a few 
microseconds.

Now I want to have the slaves also synchronized to this time frame and 
have the following dilemma:

- normally, I would like to call

// cycle begins

ecrt_master_receive(master);
ecrt_domain_process(domain1);

// do a lot of stuff

clock_gettime(CLOCK_REALTIME, &time);
ecrt_master_application_time(master, ((time.tv_sec - 946684800ULL) * 1000000000ULL + time.tv_nsec));

ecrt_master_sync_reference_clock(master);
ecrt_master_sync_slave_clocks(master);

ecrt_domain_queue(domain1);
ecrt_master_send(master);

// cycle ends, wait for next cycle

However, as the "lot of stuff" takes different amounts of time, this seems 
to be not good, as this means a few hundred microseconds jitter as to when 
the application time is set in our (1 ms long) cycle.

- therefore, I could call it that way:

// cycle begins

clock_gettime(CLOCK_REALTIME, &time);
ecrt_master_application_time(master, ((time.tv_sec - 946684800ULL) * 1000000000ULL + time.tv_nsec));

ecrt_master_sync_reference_clock(master);
ecrt_master_sync_slave_clocks(master);

ecrt_domain_queue(domain1);
ecrt_master_send(master);

// wait for frame transfer to complete

ecrt_master_receive(master);
ecrt_domain_process(domain1);

// do a lot of stuff

// cycle ends, wait for next cycle

This removes the jitter and I could also cope with the updated domain data 
being sent at the begin of the next cycle somehow. However, the 
problematic part is the "wait for frame transfer to complete". There seems 
to be no way to actually know when this has happened. Also, I experienced 
stable operation with a low as 50 us, while sometimes 200 us is needed to 
avoid "datagram UNMATCHED" messages and a short drop out of OP (working 
counter going to 0 for a moment).

>From what I read, there seems to be not a single good solution to this, or 
am I overlooking something?

Is there any way of actually checking if the frame transfer is complete? 
As I am in a realtime cycle, I could then busywait instead of using a 
fixed (probably rather large) delay.

Or can I still use the first solution? I am a bit afraid of it, as it is 
mentioned that the SYNC0 timing will be in phase with the first call to 
this function. 

Thanks for your help!
-- 
.      -Michael



More information about the Etherlab-users mailing list