Hi, The DC flow from the post below is an old version, back in the days when RTDM was first being added to the master. I no longer need the separate thread to activate the master.
I use a slave as a reference clock, adjusting the PC’s cycle to match. I haven’t used Xenomai or RT-PREMPT but they should only need something similar to rt_sleep_until(). My current DC flow is: configure master ecrt_request_master ecrt_master_create_domain (x3) configure slaves (pdos / sdos / dc) ecrt_master_get_slave // get slave info and check it matches the expected device and revision ecrt_master_slave_config ecrt_slave_config_pdos ecrt_slave_config_create_sdo_request // I create one general usage SDO per module ecrt_slave_config_reg_pdo_entry // one call per pdo entry ecrt_slave_config_sdo8 etc // configuration entries ecrt_slave_config_dc // for dc slaves prepare to run ecrt_master_setup_domain_memory // pre-setup domain memory (via one of my patches) per domain: ecrt_domain_data // get domain data address ecrt_domain_size // get domain data size allocate memory x2 // for a mask and a cache per module: calculate/cache pdo data addresses set initial module data/control values set up dc clocks: ecrt_master_application_time // set initial app time (must be in phase with realtime cycle) ecrt_master_select_reference_clock // select slave to use as reference clock ecrt_master_activate start realtime cycle (I use RTAI) rt_thread_init rt_set_oneshot_mode rt_allow_nonroot_hrt mlockall calc first wake time (in phase with initial ecrt_master_application_time call) start_rt_timer rt_make_hard_real_time realtime cycle ecrt_master_receive ecrt_domain_process x3 ecrt_domain_state // check WC / state of domains ecrt_master_state // check state of master see if any modules want to write “special” data write cached domain data ecrt_domain_queue x3 sync distributed clock // as close to ecrt_master_send as possible ecrt_master_reference_clock_time // calc diff between expected slave time and actual, after first realtime scan ecrt_master_sync_slave_clocks ecrt_master_application_time ecrt_master_send calc slave to master time drift and adjust master clock and cycle period to match see if any modules want to reset “special” data or calc extra data (eg Actual Velocity) perform application logic. note: any data to be written to the domain memory is actually written to the domain cache and mask run device logic (eg axis enable / disable logic) wait for remainder of cycle rt_sleep_until stop realtime cycle (called before wait for remainder of cycle if app is flagged to shutdown) (while continuing realtime cycle) tell modules to prepare to stop, ie stop and disable axes nicely etc once safe: ecrt_master_deactivate_slaves // from one of my patches, it stops a few shutdown errors (continue cycling until the rest of the app is ready to shutdown also) and stop rt_make_soft_real_time stop_rt_timer rt_task_delete ecrt_master_deactivate ecrt_release_master free domain cache/mask memory The call to ecrt_master_reference_clock_time() is what gives us the reference slave clock time. We compare this to our expected time and the difference is the slaves drift compared to the master PC. I cache a running history of these to calc an average drift to figure out my base cycle time in terms of the PC clock. I also gradually adjust the cycle time as required to keep the slave and master periods in sync. The application time needs to be the master PC’s time adjusted by the overall drift with the reference slaves clock. As for the Working counter changed messages I’m not really sure. Check the cable between the last two modules is good / try a new cable maybe. Regards, Graeme. From: 陈成细 [mailto:crazyintermi...@gmail.com] Sent: Friday, 25 March 2016 1:16 a.m. To: Graeme Foot Subject: Distribute Clock new flow Dear Graeme, Thanks a lot for your help during last two years . Now i can run yaskawa driver and motor with ethercat. However sometimes it will run into sync error, I am not aware the problem until i bought another secondhand Omron driver . I decided to solve this DC issue from the root, so I carefully go through all the threads from mailing list which related to DC many times. Of course your thread(http://thread.gmane.org/gmane.network.etherlab.user/1335/focus=1349) is from A-Z to solve this issue. I would like to use the same method to solve my problem, but I have following questions: 1. your DC flow: configure master ecrt_request_master ecrt_master_create_domain configure slaves (pdos / sdos / dc) ecrt_master_slave_config ecrt_slave_config_pdos ecrt_slave_config_reg_pdo_entry ecrt_slave_config_sdo8 ecrt_slave_config_dc connect to rtdm rt_dev_open(rtdm) ecrt_domain_index ecrt_rtdm_master_attach setup domain memory ecrt_master_setup_domain_memory ecrt_domain_data ecrt_domain_size create master_activate thread -------+ | start realtime | request master_activate --> | ecrt_master_activate ecrt_rtdm_master_recieve | (after first sync dc) sync dc | ecrt_rtdm_master_send | <-- | master activated ecrt_rtdm_master_recieve | ecrt_rtdm_domain_process_all | check domain state | check master state | update domain data | sync dc | ecrt_rtdm_domain_queue_all | ecrt_rtdm_master_send | | request master deactivate --> | ecrt_master_deactivate_slaves ecrt_rtdm_master_recieve | (wait for PREOP or 5s) ecrt_rtdm_domain_process_all | check domain state | check master state | update domain data | sync dc | ecrt_rtdm_domain_queue_all | ecrt_rtdm_master_send | <-- | master deactivating ecrt_rtdm_master_recieve | ecrt_master_deactivate sync dc | ecrt_rtdm_master_send | <-- | master deactivated stop realtime | stop master_activate thread + cleanup rt_dev_close(rtdm) ecrt_release_master There is a master_activate thread, can I do it in the same real time thread? But it seems you denied your previous conclusion in this thread(http://thread.gmane.org/gmane.network.etherlab.user/1412/focus=1416). I'm using RTAI but I was not calibrating my cpu-frequency. By default Linux only calibrates the cpu-freq to the PIT timer to an accuracy of 500 parts per million. So each time I rebooted I could get quite varied cpu-freq values. When they were outside a good operating range I would often get: EtherCAT WARNING 0-9: Slave did not sync after 5001 ms. And sometimes get: EtherCAT DEBUG 0-9: OP -> SAFEOP + ERROR. EtherCAT ERROR 0-9: AL status message 0x001A: "Synchronization error". The drive would then report an error code of 0x0A12 (sync error). When I changed my code to start cycling the pdo information and the dc information before calling ecrt_master_activate() the problem pretty much went away. But I would often still get the odd sync error at some later stage. Now after calibrating my cpu-freq value, doing a lot of other stuff and generally gathering more knowledge I see the original diagnosis was wrong. All that was happening was that the drives could not stay synced if the masters time cycle was too fast or too slow. Starting to cycle the dc information sooner seemed to help them stabilise better on startup but they would still sometimes loose sync at a later stage anyway. (Note: I'm setting my calibrated cpu-freq by using the "rtai_cpufreq_arg" when calling insmod on rtai_hal.ko.) How can I check my cpu-freq and define whether it get issue or not? May I have a little bit detail how to calibrate it in your case? And how about RT-PREMPT or Xenomai? By the way, I already use the lastest patches from Jun Yuan(http://lists.etherlab.org/pipermail/etherlab-users/2016/002922.html) hg clone http://hg.code.sf.net/u/mensch88/etherlabmaster -r rtleaders etherlab-dev 2 My issue is omron driver keep changing working counter like: [10353.644769] EtherCAT 0: Domain 2: Working counter changed to 2/3. [10354.652702] EtherCAT 0: Domain 2: Working counter changed to 3/3. [ 10358.496736] EtherCAT 0: Domain 2: Working counter changed to 2/3. [10359.504699] EtherCAT 0: Domain 2: Working counter changed to 3/3. Do you have any experience about it? detail Dmesg file attached. I am so sorry drop you so long email. I am appreciated that you can give any hints to help me solve this nightmare issue. Thanks very much! -- Best regards! 陈成细 R&D Engineer (\__/) (='.'=) This is Bunny. Copy and paste bunny into your (")_(") signature to help him gain world domination.
_______________________________________________ etherlab-users mailing list etherlab-users@etherlab.org http://lists.etherlab.org/mailman/listinfo/etherlab-users