[snip] Are you using the dc_clock_adjust to modify your sleep time? ie. something like [/snip]
I’ve been trying, but the results are all over the place and I’m obviously not understanding what needs to be done with the clock. My latest attempt is has the scan time ticking from anywhere between 3930 and 4100 scans per second (reported by ethercat master command) and does nothing to eliminate skipped datagrams. I don’t think I’m fundamentally understanding what needs to be done. My latest code is below. If anyone has any insights, it would be greatly appreciated. ======== int64_t dc_adjust_ns = 0 ; int32_t dc_diff_ns = 0; void calculateClockDrift(void) { uint32_t ref_time = 0; uint64_t prev_app_time = dc_time_ns; dc_time_ns = system_time_ns(); // get reference clock time to synchronize master cycle ecrt_master_reference_clock_time(master_, & ref_time); dc_diff_ns = (uint32_t) prev_app_time - ref_time; // calc drift (via un-normalised time diff) int32_t delta = dc_diff_ns - prev_dc_diff_ns; prev_dc_diff_ns = dc_diff_ns; dc_diff_ns = ((dc_diff_ns + (cycle_ns_ / 2)) % cycle_ns_) - (cycle_ns_ / 2); } #define TIMESPEC_ADD_NS(TS, NS)\ (TS).tv_nsec += (NS);\ while ((TS).tv_nsec >= NANOS_PER_SEC) {\ (TS).tv_nsec -= NANOS_PER_SEC;\ (TS).tv_sec++; } #define TIMESPEC2NSEPOCH2000(T)\ ((uint64_t)(((T).tv_sec - 946684800 ULL) * 1000000000 ULL) + (T).tv_nsec) # define TON struct timespec# define TON_ENDTIME(MS)\ time_add_ns((MS) * NANOS_PER_MILLISEC) static TON clockSyncTon_; int TON_ISDONE(struct timespec ts) { struct timespec now; clock_gettime(CLOCK_MONOTONIC, & now); if (now.tv_sec > ts.tv_sec) return 1; else if (now.tv_sec == ts.tv_sec && now.tv_nsec >= ts.tv_nsec) return 1; else return 0; } static bool wait_period(RtaiMain * inst) { int rc; bool done = false; while (!done && inst - > doScan && runAll_) { rc = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, & inst - > wakeupTime, NULL); if (rc == EFAULT) { return false; } else if (rc == EINTR) { continue; } else if (rc == EINVAL) { return false; } else { done = 1; } } TIMESPEC_ADD_NS(inst->wakeupTime, inst->cycleNs + dc_diff_ns ); return true; } static void cyclic_task(RtaiMain * inst) { clock_gettime(CLOCK_MONOTONIC, & (inst - > wakeupTime)); /* start after one second */ inst - > wakeupTime.tv_sec++; wait_period(inst); while (runAll_ && inst - > doScan) { // // Trigger Fieldbus RX here. // // ecrt_master_receive(master_); // record the time we received the data so other parts of the program // have an accurate time reading globalTickTimeNs = ton_get_ns(); ecrt_domain_process(lrwDomainMgr_.domain); ecrt_domain_process(noLrwWriteDomainMgr_.domain); ecrt_domain_process(noLrwReadDomainMgr_.domain); if (counter_) { counter_—; } else { counter_ = 4000; // check for master state check_master_state(); } … tick sub systems // // Trigger Fieldbus TX. This should be the last step // // ecrt_domain_queue(lrwDomainMgr_.domain); ecrt_domain_queue(noLrwWriteDomainMgr_.domain); ecrt_domain_queue(noLrwReadDomainMgr_.domain); clock_gettime(CLOCK_REALTIME, & dcTime_); ecrt_master_application_time( master_, TIMESPEC2NSEPOCH2000(dcTime_)); if (TON_ISDONE(clockSyncTon_)) { ecrt_master_sync_reference_clock(master_); clockSyncTon_ = TON_ENDTIME(10); // milliseconds } ecrt_master_sync_slave_clocks(master_); // send EtherCAT data ecrt_master_send(master_); calculateClockDrift(); if (!wait_period(inst)) { PRINT("%s Error with waiting! Stopping cyclic_task.\n", __FUNCTION__); inst - > doScan = false; } } } _______________________________________________ etherlab-users mailing list etherlab-users@etherlab.org http://lists.etherlab.org/mailman/listinfo/etherlab-users