Hi,

I'm trying to create an EtherCAT communication with an XMC4800, using IgH 
EtherCAT. I'm using 16.04 Ubuntu with 4.8.0-58 kernel. I downloaded the code 
from sourceforge and run the code (a bit modified, see attachment) found in 
examples/dc_user. If I use a loop frequency of 1 KHz all things go well 
(despite some datagrams UNMATCHED warnings). But if I increase the loop rate to 
5 or 10 KHz I'm seeing the error in the subject. My goal is at least 10Khz 
succesful (withoul losses) communication. Below is the output I'm getting in 
the kernel log:


Mar  8 14:42:31 mikekaram-HP-EliteBook-Folio-9470m kernel: [13658.296909] 
EtherCAT: Requesting master 0...
Mar  8 14:42:31 mikekaram-HP-EliteBook-Folio-9470m kernel: [13658.296912] 
EtherCAT: Successfully requested master 0.
Mar  8 14:42:31 mikekaram-HP-EliteBook-Folio-9470m kernel: [13658.296961] 
EtherCAT 0: Domain0: Logical address 0x00000000, 18 byte, expected working 
counter 3.
Mar  8 14:42:31 mikekaram-HP-EliteBook-Folio-9470m kernel: [13658.296962] 
EtherCAT 0:   Datagram domain0-0-main: Logical offset 0x00000000, 18 byte, type 
LRW at ffff91a5b5c9d858.
Mar  8 14:42:31 mikekaram-HP-EliteBook-Folio-9470m kernel: [13658.296981] 
EtherCAT 0: Master thread exited.
Mar  8 14:42:31 mikekaram-HP-EliteBook-Folio-9470m kernel: [13658.296983] 
EtherCAT 0: Starting EtherCAT-OP thread.
Mar  8 14:42:31 mikekaram-HP-EliteBook-Folio-9470m kernel: [13658.297040] 
EtherCAT WARNING 0: 15 datagrams UNMATCHED!
Mar  8 14:42:32 mikekaram-HP-EliteBook-Folio-9470m kernel: [13659.296406] 
EtherCAT WARNING 0: 13437 datagrams UNMATCHED!
Mar  8 14:42:32 mikekaram-HP-EliteBook-Folio-9470m kernel: [13659.297430] 
EtherCAT WARNING: Datagram ffff91a5b5c9d858 (domain0-0-main) was SKIPPED 6725 
times.
Mar  8 14:42:33 mikekaram-HP-EliteBook-Folio-9470m kernel: [13660.296475] 
EtherCAT WARNING 0: 13455 datagrams UNMATCHED!
Mar  8 14:42:33 mikekaram-HP-EliteBook-Folio-9470m kernel: [13660.298486] 
EtherCAT WARNING: Datagram ffff91a5b5c9d858 (domain0-0-main) was SKIPPED 6734 
times.
Mar  8 14:42:34 mikekaram-HP-EliteBook-Folio-9470m kernel: [13661.296543] 
EtherCAT WARNING 0: 13442 datagrams UNMATCHED!
Mar  8 14:42:34 mikekaram-HP-EliteBook-Folio-9470m kernel: [13661.299562] 
EtherCAT WARNING: Datagram ffff91a5b5c9d858 (domain0-0-main) was SKIPPED 6726 
times.
Mar  8 14:42:35 mikekaram-HP-EliteBook-Folio-9470m kernel: [13662.296611] 
EtherCAT WARNING 0: 13388 datagrams UNMATCHED!
Mar  8 14:42:35 mikekaram-HP-EliteBook-Folio-9470m kernel: [13662.300630] 
EtherCAT WARNING: Datagram ffff91a5b5c9d858 (domain0-0-main) was SKIPPED 6700 
times.
Mar  8 14:42:36 mikekaram-HP-EliteBook-Folio-9470m kernel: [13663.296679] 
EtherCAT WARNING 0: 13414 datagrams UNMATCHED!
Mar  8 14:42:36 mikekaram-HP-EliteBook-Folio-9470m kernel: [13663.301699] 
EtherCAT WARNING: Datagram ffff91a5b5c9d858 (domain0-0-main) was SKIPPED 6715 
times.
Mar  8 14:42:36 mikekaram-HP-EliteBook-Folio-9470m kernel: [13663.310699] 
EtherCAT WARNING 0-0: Slave did not sync after 5000 ms.
Mar  8 14:42:36 mikekaram-HP-EliteBook-Folio-9470m kernel: [13663.312411] 
EtherCAT ERROR 0-0: Failed to set SAFEOP state, slave refused state change 
(PREOP + ERROR).
Mar  8 14:42:36 mikekaram-HP-EliteBook-Folio-9470m kernel: [13663.312949] 
EtherCAT ERROR 0-0: AL status message 0x0036: "DC Sync0 Cycle Time".
Mar  8 14:42:36 mikekaram-HP-EliteBook-Folio-9470m kernel: [13663.313501] 
EtherCAT 0-0: Acknowledged state PREOP.
Mar  8 14:42:37 mikekaram-HP-EliteBook-Folio-9470m kernel: [13664.296893] 
EtherCAT WARNING 0: 14550 datagrams UNMATCHED!
Mar  8 14:42:37 mikekaram-HP-EliteBook-Folio-9470m kernel: [13664.302791] 
EtherCAT WARNING: Datagram ffff91a5b5c9d858 (domain0-0-main) was SKIPPED 7285 
times.
Mar  8 14:42:38 mikekaram-HP-EliteBook-Folio-9470m kernel: [13665.296872] 
EtherCAT WARNING 0: 14323 datagrams UNMATCHED!
Mar  8 14:42:38 mikekaram-HP-EliteBook-Folio-9470m kernel: [13665.303849] 
EtherCAT WARNING: Datagram ffff91a5b5c9d858 (domain0-0-main) was SKIPPED 7165 
times.
Mar  8 14:42:39 mikekaram-HP-EliteBook-Folio-9470m kernel: [13666.296910] 
EtherCAT WARNING 0: 14357 datagrams UNMATCHED!
Mar  8 14:42:39 mikekaram-HP-EliteBook-Folio-9470m kernel: [13666.304931] 
EtherCAT WARNING: Datagram ffff91a5b5c9d858 (domain0-0-main) was SKIPPED 7184 
times.
Mar  8 14:42:40 mikekaram-HP-EliteBook-Folio-9470m kernel: [13667.296989] 
EtherCAT WARNING 0: 14185 datagrams UNMATCHED!
Mar  8 14:42:40 mikekaram-HP-EliteBook-Folio-9470m kernel: [13667.305995] 
EtherCAT WARNING: Datagram ffff91a5b5c9d858 (domain0-0-main) was SKIPPED 7104 
times.
Mar  8 14:42:41 mikekaram-HP-EliteBook-Folio-9470m kernel: [13668.297188] 
EtherCAT WARNING 0: 14166 datagrams UNMATCHED!
Mar  8 14:42:41 mikekaram-HP-EliteBook-Folio-9470m kernel: [13668.307062] 
EtherCAT WARNING: Datagram ffff91a5b5c9d858 (domain0-0-main) was SKIPPED 7085 
times.
Mar  8 14:42:42 mikekaram-HP-EliteBook-Folio-9470m kernel: [13669.297098] 
EtherCAT WARNING 0: 14209 datagrams UNMATCHED!
Mar  8 14:42:42 mikekaram-HP-EliteBook-Folio-9470m kernel: [13669.308106] 
EtherCAT WARNING: Datagram ffff91a5b5c9d858 (domain0-0-main) was SKIPPED 7112 
times.
Mar  8 14:42:43 mikekaram-HP-EliteBook-Folio-9470m kernel: [13670.297189] 
EtherCAT WARNING 0: 13986 datagrams UNMATCHED!
Mar  8 14:42:43 mikekaram-HP-EliteBook-Folio-9470m kernel: [13670.309191] 
EtherCAT WARNING: Datagram ffff91a5b5c9d858 (domain0-0-main) was SKIPPED 7005 
times.
Mar  8 14:42:44 mikekaram-HP-EliteBook-Folio-9470m kernel: [13671.297272] 
EtherCAT WARNING 0: 14235 datagrams UNMATCHED!
Mar  8 14:42:44 mikekaram-HP-EliteBook-Folio-9470m kernel: [13671.310255] 
EtherCAT WARNING: Datagram ffff91a5b5c9d858 (domain0-0-main) was SKIPPED 7122 
times.
Mar  8 14:42:45 mikekaram-HP-EliteBook-Folio-9470m kernel: [13672.297425] 
EtherCAT WARNING 0: 14340 datagrams UNMATCHED!
Mar  8 14:42:45 mikekaram-HP-EliteBook-Folio-9470m kernel: [13672.311322] 
EtherCAT WARNING: Datagram ffff91a5b5c9d858 (domain0-0-main) was SKIPPED 7185 
times.
Mar  8 14:42:46 mikekaram-HP-EliteBook-Folio-9470m kernel: [13673.297404] 
EtherCAT WARNING 0: 14455 datagrams UNMATCHED!
Mar  8 14:42:46 mikekaram-HP-EliteBook-Folio-9470m kernel: [13673.312406] 
EtherCAT WARNING: Datagram ffff91a5b5c9d858 (domain0-0-main) was SKIPPED 7227 
times.
Mar  8 14:42:47 mikekaram-HP-EliteBook-Folio-9470m kernel: [13674.297464] 
EtherCAT WARNING 0: 14545 datagrams UNMATCHED!
Mar  8 14:42:47 mikekaram-HP-EliteBook-Folio-9470m kernel: [13674.313523] 
EtherCAT WARNING: Datagram ffff91a5b5c9d858 (domain0-0-main) was SKIPPED 7281 
times.
Mar  8 14:42:48 mikekaram-HP-EliteBook-Folio-9470m kernel: [13675.297525] 
EtherCAT WARNING 0: 14760 datagrams UNMATCHED!
Mar  8 14:42:48 mikekaram-HP-EliteBook-Folio-9470m kernel: [13675.314541] 
EtherCAT WARNING: Datagram ffff91a5b5c9d858 (domain0-0-main) was SKIPPED 7384 
times.
Mar  8 14:42:49 mikekaram-HP-EliteBook-Folio-9470m kernel: [13676.202128] 
EtherCAT 0: Releasing master...
Mar  8 14:42:49 mikekaram-HP-EliteBook-Folio-9470m kernel: [13676.202166] 
EtherCAT 0: Master thread exited.
Mar  8 14:42:49 mikekaram-HP-EliteBook-Folio-9470m kernel: [13676.202179] 
EtherCAT 0: Starting EtherCAT-IDLE thread.
Mar  8 14:42:49 mikekaram-HP-EliteBook-Folio-9470m kernel: [13676.202260] 
EtherCAT 0: Released.
Mar  8 14:42:49 mikekaram-HP-EliteBook-Folio-9470m kernel: [13676.202274] 
EtherCAT ERROR 0-0: Failed to receive AL state datagram: Datagram initialized.


What am I doing wrong? Could you please offer me some advice, to achieve my 
goal?

Regards,

Mike Karamousadakis
/*****************************************************************************
 *
 *  $Id$
 *
 *  Copyright (C) 2007-2009  Florian Pose, Ingenieurgemeinschaft IgH
 *
 *  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, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  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 <time.h>
#include <sys/mman.h>
#include <malloc.h>

/****************************************************************************/

#include "ecrt.h"

/****************************************************************************/

// Application parameters
#define FREQUENCY 10000 //define frequency in Hz
#define CLOCK_TO_USE CLOCK_REALTIME
#define MEASURE_TIMING
#define SetBit(A,k)     ( A[(k/8)] |= (1 << (k%8)) )
#define ClearBit(A,k)   ( A[(k/8)] &= ~(1 << (k%8)) )
#define RUN_TIME 30 // run time in seconds
// int nLoops = 10000;
double ttotal = 0;
uint8_t write_index = 64;

/****************************************************************************/

#define NSEC_PER_SEC (1000000000L)
#define PERIOD_NS (NSEC_PER_SEC / FREQUENCY)
#define NUM_SLAVES 1
#define DIFF_NS(A, B) (((B).tv_sec - (A).tv_sec) * NSEC_PER_SEC + \
	(B).tv_nsec - (A).tv_nsec)

#define TIMESPEC2NS(T) ((uint64_t) (T).tv_sec * NSEC_PER_SEC + (T).tv_nsec)

/****************************************************************************/

// 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 = {};

/****************************************************************************/

// process data
static uint8_t *domain1_pd = NULL;

#define BusCouplerPos    0, 0
#define DigOutSlavePos   0, 1
#define CounterSlavePos  0, 2

#define Beckhoff_EK1100 0x00000A12, 0x00000000
#define Beckhoff_EL2008 0x00000A12, 0x00000000
// #define IDS_Counter     0x000012ad, 0x05de3052

// offsets for PDO entries
static int off_dig_out;
static int off_counter_in;
static int off_counter_out;

static unsigned int counter = 0;
static unsigned int blink = 0;
static unsigned int sync_ref_counter = 0;
const struct timespec cycletime = {0, PERIOD_NS};
char * s, *d;
FILE * f;

/*****************************************************************************/

struct timespec timespec_add(struct timespec time1, struct timespec time2)
{
	struct timespec result;

	if ((time1.tv_nsec + time2.tv_nsec) >= NSEC_PER_SEC) {
		result.tv_sec = time1.tv_sec + time2.tv_sec + 1;
		result.tv_nsec = time1.tv_nsec + time2.tv_nsec - NSEC_PER_SEC;
	} else {
		result.tv_sec = time1.tv_sec + time2.tv_sec;
		result.tv_nsec = time1.tv_nsec + time2.tv_nsec;
	}

	return result;
}

/*****************************************************************************/

void check_domain1_state(void)
{
    ec_domain_state_t ds;

    ecrt_domain_state(domain1, &ds);

    if (ds.working_counter != domain1_state.working_counter)
        printf("Domain1: WC %u.\n", ds.working_counter);
    if (ds.wc_state != domain1_state.wc_state)
        printf("Domain1: State %u.\n", ds.wc_state);

    domain1_state = ds;
}

/*****************************************************************************/

void check_master_state(void)
{
    ec_master_state_t ms;

    ecrt_master_state(master, &ms);

	if (ms.slaves_responding != master_state.slaves_responding)
        printf("%u slave(s).\n", ms.slaves_responding);
    if (ms.al_states != master_state.al_states)
        printf("AL states: 0x%02X.\n", ms.al_states);
    if (ms.link_up != master_state.link_up)
        printf("Link is %s.\n", ms.link_up ? "up" : "down");

    master_state = ms;
}

/****************************************************************************/
void set_output_bit (uint8_t * data_ptr, uint8_t index)
{
//    uint8 *data_ptr;
//    data_ptr = ec_slave[slave_no].outputs;
   /* Move pointer to correct module index*/
//    data_ptr += module_index * 2;
   /* Read value byte by byte since all targets can't handle misaligned
 addresses
    */
//   *data_ptr++ = (value >> 0) & 0xFF;
//   *data_ptr++ = (value >> 8) & 0xFF;
//   printf("Value of shift is: %d, array index is: %d and bit index is: %d\n",value,value/8,value%8);
    SetBit(data_ptr,index);
//    if(value == 0)
//       ClearBit(data_ptr,71);
//    else
//    {
//       printf("Clearing %d bit\n",value-1);
//       ClearBit(data_ptr,value-1);
//    }

}
uint16_t process_input_int16(uint8_t * data_ptr, uint8_t index)
{
    // uint8 * data_ptr;
    uint16_t return_value = 0x0000;
    // data_ptr = ec_slave[slave_no].inputs;
    /* Move pointer to correct module index*/
    // data_ptr += module_index * 2;
    return_value = data_ptr[index+1];
    return_value = return_value << 8;
    return_value |= data_ptr[index];
//    return_value = ((data_ptr[index]>>8)&0xFFFF) | (data_ptr[index+1]<<8&0xFFFF);
//    printf("Return Value is: %d\n",return_value);
    return return_value;
}

void cyclic_task()
{
    struct timespec wakeupTime, time;
    uint16_t noise;
#ifdef MEASURE_TIMING
    struct timespec startTime, endTime, lastStartTime = {},breakTime,currentTime,offsetTime = {RUN_TIME,0};
    uint32_t period_ns = 0, exec_ns = 0, latency_ns = 0,
             latency_min_ns = 0, latency_max_ns = 0,
             period_min_ns = 0, period_max_ns = 0,
             exec_min_ns = 0, exec_max_ns = 0;
#endif
    set_output_bit(domain1_pd + off_dig_out, write_index);
    // get current time
    clock_gettime(CLOCK_TO_USE, &wakeupTime);
    clock_gettime(CLOCK_TO_USE, &breakTime);
    breakTime = timespec_add(breakTime, offsetTime);
	do {
		wakeupTime = timespec_add(wakeupTime, cycletime);
        clock_nanosleep(CLOCK_TO_USE, TIMER_ABSTIME, &wakeupTime, NULL);

#ifdef MEASURE_TIMING
        clock_gettime(CLOCK_TO_USE, &startTime);
        latency_ns = DIFF_NS(wakeupTime, startTime);
        period_ns = DIFF_NS(lastStartTime, startTime);
        exec_ns = DIFF_NS(lastStartTime, endTime);
        lastStartTime = startTime;

        if (latency_ns > latency_max_ns) {
            latency_max_ns = latency_ns;
        }
        if (latency_ns < latency_min_ns) {
            latency_min_ns = latency_ns;
        }
        if (period_ns > period_max_ns) {
            period_max_ns = period_ns;
        }
        if (period_ns < period_min_ns) {
            period_min_ns = period_ns;
        }
        if (exec_ns > exec_max_ns) {
            exec_max_ns = exec_ns;
        }
        if (exec_ns < exec_min_ns) {
            exec_min_ns = exec_ns;
        }
#endif

		// receive process data
		ecrt_master_receive(master);
		ecrt_domain_process(domain1);
        // noise = process_input_int16(domain1_pd + off_counter_in,0);
        // printf("I: %2.2d \n", noise);
		// check process data state (optional)
		// check_domain1_state();

		if (counter) {
			counter--;
		} else { // do this at 100 Hz
			counter = FREQUENCY/100;

			// check for master state (optional)
			// check_master_state();

#ifdef MEASURE_TIMING
            // output timing stats
            // printf("period     %10u ... %10u\n",
            //         period_min_ns, period_max_ns);
            // printf("exec       %10u ... %10u\n",
            //         exec_min_ns, exec_max_ns);
            // printf("latency    %10u ... %10u\n",
            //         latency_min_ns, latency_max_ns);
            // sprintf(d,"period     %10u ... %10u\n",
            //         period_min_ns, period_max_ns);
            // fprintf(f,"%s",d);
            // sprintf(d,"exec       %10u ... %10u\n",
            //         exec_min_ns, exec_max_ns);
            // fprintf(f,"%s",d);
            // sprintf(d,"latency    %10u ... %10u\n",
            //         latency_min_ns, latency_max_ns);
            // fprintf(f,"%s",d);
            period_max_ns = 0;
            period_min_ns = 0xffffffff;
            exec_max_ns = 0;
            exec_min_ns = 0xffffffff;
            latency_max_ns = 0;
            latency_min_ns = 0xffffffff;
#endif

			// calculate new process data
		}

		// write process data
		// set_output_bit(domain1_pd + off_dig_out, write_index);
		// EC_WRITE_U8(domain1_pd + off_counter_out, blink ? 0x00 : 0x02);
        // printf("O:");
        // for(int j = 0 ; j < 9; j++)
        //     printf(" %2.2x", *(domain1_pd + j));
        // printf("\n");

		// write application time to master
		clock_gettime(CLOCK_TO_USE, &time);
		ecrt_master_application_time(master, TIMESPEC2NS(time));

		if (sync_ref_counter) {
			sync_ref_counter--;
		} else {
			sync_ref_counter = 10; // sync every cycle
			ecrt_master_sync_reference_clock(master);
		}
		ecrt_master_sync_slave_clocks(master);

		// send process data
		ecrt_domain_queue(domain1);
		ecrt_master_send(master);

#ifdef MEASURE_TIMING
        clock_gettime(CLOCK_TO_USE, &endTime);
#endif
    clock_gettime(CLOCK_TO_USE, &currentTime);
    }while(DIFF_NS(currentTime,breakTime) > 0);
}

/****************************************************************************/

int main(int argc, char **argv)
{
    ec_slave_config_t *sc;

	if (mlockall(MCL_CURRENT | MCL_FUTURE) == -1) {
		perror("mlockall failed");
		return -1;
	}

    master = ecrt_request_master(0);
    if (!master)
        return -1;
    domain1 = ecrt_master_create_domain(master);
    if (!domain1)
        return -1;
    // Create configuration for bus coupler
    sc = ecrt_master_slave_config(master, BusCouplerPos, Beckhoff_EK1100);
    if (!sc){
    	fprintf(stderr, "Failed to get slave configuration.\n");
        return -1;
    }

    // if (!(sc = ecrt_master_slave_config(master,
    //                 DigOutSlavePos, Beckhoff_EL2008))) {
    //     fprintf(stderr, "Failed to get slave configuration.\n");
    //     return -1;
    // }

    off_dig_out = ecrt_slave_config_reg_pdo_entry(sc,
            0x7000, 1, domain1, NULL);
    if (off_dig_out < 0)
        return -1;
    printf("Offset digital out is: %d\n",off_dig_out);

	// if (!(sc = ecrt_master_slave_config(master,
	// 				CounterSlavePos, IDS_Counter))) {
 //        fprintf(stderr, "Failed to get slave configuration.\n");
 //        return -1;
	// }

	off_counter_in = ecrt_slave_config_reg_pdo_entry(sc,
			0x6000, 1, domain1, NULL);
	if (off_counter_in < 0)
        return -1;
    printf("Offset counter in is: %d\n",off_counter_in);
	// off_counter_out = ecrt_slave_config_reg_pdo_entry(sc,
	// 		0x7020, 1, domain1, NULL);
	// if (off_counter_out < 0)
 //        return -1;

    // configure SYNC signals for this slave
    // shift time = 4400000
	ecrt_slave_config_dc(sc, 0x0700, PERIOD_NS, PERIOD_NS/2, 0, 0);
    printf("Activating master...\n");
    if (ecrt_master_activate(master))
        return -1;

    if (!(domain1_pd = ecrt_domain_data(domain1))) {
        return -1;
    }

    pid_t pid = getpid();
    if (setpriority(PRIO_PROCESS, pid, -19))
        fprintf(stderr, "Warning: Failed to set priority: %s\n",
                strerror(errno));
// ************************************************
    s=malloc(50*sizeof(char));
    d=malloc(50*sizeof(char));
    sprintf(s,"./outputs/ectest_dc_res_time_%d_%ld_ns",NUM_SLAVES,PERIOD_NS);

    f=fopen(s,"w");

// ************************************************
	printf("Starting cyclic function.\n");
    cyclic_task();

    return 0;
}

/****************************************************************************/
_______________________________________________
etherlab-users mailing list
[email protected]
http://lists.etherlab.org/mailman/listinfo/etherlab-users

Reply via email to