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

Reply via email to