Hi Graeme, Thanks for the answer. I have 4 modules (EK1100, EL1008, EL2004 and EL3202) from which only the BusCoupler and the EL2004 (also used in Xenomai example) are active.
Here are my delays: $ ethercat slaves -v | grep delay DC system time transmission delay: 0 ns DC system time transmission delay: 145 ns DC system time transmission delay: 285 ns DC system time transmission delay: 440 ns I tested the application over last night and had no losses, 12,5kHz seems stable for my configuration. This means 80000ns cycle time so I dont think the transmission delays are a factor here. The task itself is not doing much, just inverting the output every other second + the added rt_printf of the cycle_counter. It's basically the same as the xenomai example in ./examples/xenomai of the master sources. I also set the task to the maximum priority (99). I attached the example with all my changes. If anyone uses Xenomai and has an EL2004 he may if he can get better results. I will also test it with Xenomai3 and a newer kernel (3.16) in the future. Best regards, Christoph On 09/28/2016 11:24 PM, Graeme Foot wrote:
Hi, I don't use xenomai so can't comment on that side, but just curious, how many ethercat modules do you have? Also, if you run the ethercat command: ethercat slaves -v | grep 'transmission delay' What is the delay time at the last module? This is how long the ethercat frame takes to reach that module. It will then also take the same amount of time to return (assuming a linear topology). You will also need to factor in processing time overhead of the master to prepare and send the frame and receive the frame, and also add the worst case jitter time. This is in theory the shortest turnaround time you can expect per frame. It does not factor in any processing time your application may need. Regards, Graeme. -----Original Message----- From: etherlab-users [mailto:etherlab-users-boun...@etherlab.org] On Behalf Of Christoph Schröder Sent: Thursday, 29 September 2016 3:25 a.m. To: etherlab-users@etherlab.org Subject: [etherlab-users] Xenomai performance Hi all, I am currently testing the EtherCAT master with Xenomai 2.6.5 on a Debian wheezy (ipipe patched kernel 3.2). Using the xenomai example from the master I can go up to 12,5kHz (maybe a bit more). I got lost frames from time to time if I go up to 15kHz and a lot of lost frames if I go up to 20kHz. This is a lot better than non-rt, but in the master documentation there was noted that they could go up to 25kHz on a 2GHz System with RTAI. My testsystem is a Core i5-4690 CPU @ 3.50GHz. I configured everything as described in the Xenomai installation instruction. Are my results reasonable resp. is RTAI simply better or should I expect some misconfiguration? My results from the xenomai latency test seem to be fine. $ sudo ./xeno latency -T 25 == Sampling period: 100 us == Test mode: periodic user-mode task == All results in microseconds warming up... RTT| 00:00:01 (periodic user-mode task, 100 us period, priority 99) RTH|----lat min|----lat avg|----lat max|-overrun|---msw|---lat best|--lat worst RTD| -2.307| -2.152| 0.550| 0| 0| -2.307| 0.550 RTD| -2.516| -2.160| 4.011| 0| 0| -2.516| 4.011 RTD| -2.319| -2.170| 0.515| 0| 0| -2.516| 4.011 RTD| -2.324| -2.165| -0.322| 0| 0| -2.516| 4.011 RTD| -2.336| -2.127| 2.644| 0| 0| -2.516| 4.011 RTD| -2.350| -2.146| 2.139| 0| 0| -2.516| 4.011 RTD| -2.542| -2.160| -0.075| 0| 0| -2.542| 4.011 RTD| -2.363| -2.146| 2.111| 0| 0| -2.542| 4.011 RTD| -2.590| -2.156| 0.461| 0| 0| -2.590| 4.011 RTD| -2.703| -2.158| -1.017| 0| 0| -2.703| 4.011 RTD| -2.701| -2.157| 6.590| 0| 0| -2.703| 6.590 RTD| -2.695| -2.156| -1.049| 0| 0| -2.703| 6.590 RTD| -2.684| -2.158| 0.496| 0| 0| -2.703| 6.590 RTD| -2.712| -2.154| -1.079| 0| 0| -2.712| 6.590 RTD| -2.693| -2.158| 6.106| 0| 0| -2.712| 6.590 RTD| -2.700| -2.159| -1.005| 0| 0| -2.712| 6.590 RTD| -2.712| -2.156| -0.882| 0| 0| -2.712| 6.590 RTD| -2.642| -2.159| -0.836| 0| 0| -2.712| 6.590 RTD| -2.608| -2.152| 5.227| 0| 0| -2.712| 6.590 RTD| -2.686| -2.158| -0.742| 0| 0| -2.712| 6.590 RTD| -2.653| -2.158| 0.883| 0| 0| -2.712| 6.590 RTT| 00:00:22 (periodic user-mode task, 100 us period, priority 99) RTH|----lat min|----lat avg|----lat max|-overrun|---msw|---lat best|--lat worst RTD| -2.723| -2.160| -1.258| 0| 0| -2.723| 6.590 RTD| -2.643| -2.161| 0.059| 0| 0| -2.723| 6.590 RTD| -2.366| -2.168| -0.458| 0| 0| -2.723| 6.590 ---|-----------|-----------|-----------|--------|------|---------------- ---|-----------|-----------|-----------|--------|------|--------- RTS| -2.723| -2.156| 6.590| 0| 0| 00:00:25/00:00:25 Thanks and best regards, Christoph ________________________________ Helmholtz-Zentrum Berlin für Materialien und Energie GmbH Mitglied der Hermann von Helmholtz-Gemeinschaft Deutscher Forschungszentren e.V. Aufsichtsrat: Vorsitzender Dr. Karl Eugen Huthmacher, stv. Vorsitzende Dr. Jutta Koch-Unterseher Geschäftsführung: Prof. Dr. Anke Rita Kaysser-Pyzalla, Thomas Frederking Sitz Berlin, AG Charlottenburg, 89 HRB 5583 Postadresse: Hahn-Meitner-Platz 1 D-14109 Berlin http://www.helmholtz-berlin.de _______________________________________________ etherlab-users mailing list etherlab-users@etherlab.org http://lists.etherlab.org/mailman/listinfo/etherlab-users
________________________________ Helmholtz-Zentrum Berlin für Materialien und Energie GmbH Mitglied der Hermann von Helmholtz-Gemeinschaft Deutscher Forschungszentren e.V. Aufsichtsrat: Vorsitzender Dr. Karl Eugen Huthmacher, stv. Vorsitzende Dr. Jutta Koch-Unterseher Geschäftsführung: Prof. Dr. Anke Rita Kaysser-Pyzalla, Thomas Frederking Sitz Berlin, AG Charlottenburg, 89 HRB 5583 Postadresse: Hahn-Meitner-Platz 1 D-14109 Berlin http://www.helmholtz-berlin.de
/****************************************************************************** * * $Id: main.c,v 3bdd7a747fae 2012/09/20 13:28:25 fp $ * * Copyright (C) 2009-2010 Moehwald GmbH B. Benner * 2011 IgH Andreas Stewering-Bone * 2012 Florian Pose <f...@igh-essen.com> * * This file is part of the IgH EtherCAT master * * The IgH EtherCAT Master is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version 2, as * published by the Free Software Foundation. * * The IgH EtherCAT master is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. * * You should have received a copy of the GNU General Public License along * with the IgH EtherCAT master. If not, see <http://www.gnu.org/licenses/>. * * --- * * The license mentioned above concerns the source code only. Using the * EtherCAT technology and brand is only permitted in compliance with the * industrial property and similar rights of Beckhoff Automation GmbH. * *****************************************************************************/ #include <errno.h> #include <signal.h> #include <stdio.h> #include <string.h> #include <sys/resource.h> #include <sys/time.h> #include <sys/types.h> #include <unistd.h> #include <sys/mman.h> #include <rtdm/rtdm.h> #include <native/task.h> #include <native/sem.h> #include <native/mutex.h> #include <native/timer.h> #include <rtdk.h> #include <pthread.h> #include "ecrt.h" #define FREQUENCY 12500 #define NSEC_PER_SEC (1000000000L) #define PERIOD_NS (NSEC_PER_SEC / FREQUENCY) RT_TASK my_task; static int run = 1; /****************************************************************************/ // EtherCAT static ec_master_t *master = NULL; static ec_master_state_t master_state = {}; static ec_domain_t *domain1 = NULL; static ec_domain_state_t domain1_state = {}; static uint8_t *domain1_pd = NULL; static ec_slave_config_t *sc_dig_out_01 = NULL; /****************************************************************************/ // process data #define BusCoupler01_Pos 0, 0 #define DigOutSlave01_Pos 0, 2 #define Beckhoff_EK1100 0x00000002, 0x044c2c52 #define Beckhoff_EL2004 0x00000002, 0x07d43052 // offsets for PDO entries static unsigned int off_dig_out0 = 0; // process data const static ec_pdo_entry_reg_t domain1_regs[] = { {DigOutSlave01_Pos, Beckhoff_EL2004, 0x7000, 0x01, &off_dig_out0, NULL}, {} }; /****************************************************************************/ /* Slave 1, "EL2004" * Vendor ID: 0x00000002 * Product code: 0x07d43052 * Revision number: 0x00100000 */ ec_pdo_entry_info_t slave_1_pdo_entries[] = { {0x7000, 0x01, 1}, /* Output */ {0x7010, 0x01, 1}, /* Output */ {0x7020, 0x01, 1}, /* Output */ {0x7030, 0x01, 1}, /* Output */ }; ec_pdo_info_t slave_1_pdos[] = { {0x1600, 1, slave_1_pdo_entries + 0}, /* Channel 1 */ {0x1601, 1, slave_1_pdo_entries + 1}, /* Channel 2 */ {0x1602, 1, slave_1_pdo_entries + 2}, /* Channel 3 */ {0x1603, 1, slave_1_pdo_entries + 3}, /* Channel 4 */ }; ec_sync_info_t slave_1_syncs[] = { {0, EC_DIR_OUTPUT, 4, slave_1_pdos + 0, EC_WD_ENABLE}, {0xff} }; /***************************************************************************** * Realtime task ****************************************************************************/ void rt_check_domain_state(void) { ec_domain_state_t ds = {}; ecrt_domain_state(domain1, &ds); if (ds.working_counter != domain1_state.working_counter) { rt_printf("Domain1: WC %u.\n", ds.working_counter); } if (ds.wc_state != domain1_state.wc_state) { rt_printf("Domain1: State %u.\n", ds.wc_state); } domain1_state = ds; } /****************************************************************************/ void rt_check_master_state(void) { ec_master_state_t ms; ecrt_master_state(master, &ms); if (ms.slaves_responding != master_state.slaves_responding) { rt_printf("%u slave(s).\n", ms.slaves_responding); } if (ms.al_states != master_state.al_states) { rt_printf("AL states: 0x%02X.\n", ms.al_states); } if (ms.link_up != master_state.link_up) { rt_printf("Link is %s.\n", ms.link_up ? "up" : "down"); } master_state = ms; } /****************************************************************************/ void my_task_proc(void *arg) { u_int64_t cycle_counter = 0; unsigned int blink = 0; rt_task_set_periodic(NULL, TM_NOW, PERIOD_NS); // ns while (run) { rt_task_wait_period(NULL); cycle_counter++; // receive EtherCAT frames ecrt_master_receive(master); ecrt_domain_process(domain1); rt_check_domain_state(); if (!(cycle_counter % FREQUENCY)) { rt_check_master_state(); rt_printf("Cycle_counter %i\n", cycle_counter); } if (!(cycle_counter % FREQUENCY)) { blink = !blink; } EC_WRITE_U8(domain1_pd + off_dig_out0, blink ? 0x0 : 0x0F); // send process data ecrt_domain_queue(domain1); ecrt_master_send(master); } } /**************************************************************************** * Signal handler ***************************************************************************/ void signal_handler(int sig) { run = 0; } /**************************************************************************** * Main function ***************************************************************************/ int main(int argc, char *argv[]) { ec_slave_config_t *sc; int ret; /* Perform auto-init of rt_print buffers if the task doesn't do so */ rt_print_auto_init(1); signal(SIGTERM, signal_handler); signal(SIGINT, signal_handler); mlockall(MCL_CURRENT | MCL_FUTURE); printf("Requesting master...\n"); master = ecrt_request_master(0); if (!master) { return -1; } domain1 = ecrt_master_create_domain(master); if (!domain1) { return -1; } printf("Creating slave configurations...\n"); // Create configuration for bus coupler sc = ecrt_master_slave_config(master, BusCoupler01_Pos, Beckhoff_EK1100); if (!sc) { return -1; } sc_dig_out_01 = ecrt_master_slave_config(master, DigOutSlave01_Pos, Beckhoff_EL2004); if (!sc_dig_out_01) { fprintf(stderr, "Failed to get slave configuration.\n"); return -1; } if (ecrt_slave_config_pdos(sc_dig_out_01, EC_END, slave_1_syncs)) { fprintf(stderr, "Failed to configure PDOs.\n"); return -1; } if (ecrt_domain_reg_pdo_entry_list(domain1, domain1_regs)) { fprintf(stderr, "PDO entry registration failed!\n"); return -1; } printf("Activating master...\n"); if (ecrt_master_activate(master)) { return -1; } if (!(domain1_pd = ecrt_domain_data(domain1))) { fprintf(stderr, "Failed to get domain data pointer.\n"); return -1; } ret = rt_task_create(&my_task, "my_task", 0, 99, T_FPU); if (ret < 0) { fprintf(stderr, "Failed to create task: %s\n", strerror(-ret)); return -1; } printf("Starting my_task...\n"); ret = rt_task_start(&my_task, &my_task_proc, NULL); if (ret < 0) { fprintf(stderr, "Failed to start task: %s\n", strerror(-ret)); return -1; } while (run) { sched_yield(); } printf("Deleting realtime task...\n"); rt_task_delete(&my_task); printf("End of Program\n"); ecrt_release_master(master); return 0; } /****************************************************************************/
_______________________________________________ etherlab-users mailing list etherlab-users@etherlab.org http://lists.etherlab.org/mailman/listinfo/etherlab-users