[etherlab-dev] A problem related to the pdo communication

Jinyoung Choi kbkbc88 at gmail.com
Fri Nov 30 11:20:07 CET 2012


Hi all, my name CJ from south korea.

I modified an example in /example/user/main.c

My goal is to communicate with slave motor drive(epos3) by using ethercat
through SDO and PDO messages.

My slave drive can get into OP state like these messages

Activating master...

Starting timer...

Started.

1 slave(s).

AL states: 0x02.

Link is up.

EPOS3 slave 0 State 0x02.

EPOS3 slave 0: online.

Domain: WC 3.

Domain: State 2.

AL states: 0x08.

EPOS3 slave 0 State 0x08.

EPOS3 slave 0: operational.


and kernel messages are like this,

...

[29145.133927] EtherCAT DEBUG 0: Stopping master thread.

[29145.133930] EtherCAT DEBUG 0: Master IDLE thread exiting...

[29145.133952] EtherCAT 0: Master thread exited.

[29145.133954] EtherCAT DEBUG 0: FSM datagram is ffff8800527bd648.

[29145.133955] EtherCAT 0: Starting EtherCAT-OP thread.

[29145.133973] EtherCAT DEBUG 0: mmap()

[29145.133975] EtherCAT DEBUG 0: Vma fault, virtual_address =
00007fb7e9b61000, offset = 0, page = ffffea00011ffe30

[29145.134008] EtherCAT DEBUG 0: Operation thread running with fsm interval
= 10000 us, max data size=112500

[29145.134010] EtherCAT WARNING 0: 1 datagram UNMATCHED!

[29145.143508] EtherCAT DEBUG 0: Configuration changed (aborting state
check).

[29145.143511] EtherCAT DEBUG 0: Writing system time offsets...

[29145.143512] EtherCAT WARNING 0: No app_time received up to now, but
master already active.

[29145.143513] EtherCAT DEBUG 0: Requesting OP...

[29145.181179] EtherCAT DEBUG 0-0: Changing state from PREOP to OP.

[29145.181182] EtherCAT DEBUG 0-0: Configuring...

[29145.215005] EtherCAT DEBUG 0-0: Now in INIT.

[29145.215007] EtherCAT DEBUG 0-0: Clearing FMMU configurations...

[29145.235006] EtherCAT DEBUG 0-0: Clearing sync manager configurations...

[29145.255046] EtherCAT DEBUG 0-0: Clearing DC assignment...

[29145.274967] EtherCAT DEBUG 0-0: Configuring mailbox sync managers...

[29145.274995] EtherCAT DEBUG 0-0: SM0: Addr 0x1000, Size 1024, Ctrl 0x26,
En 1

[29145.274997] EtherCAT DEBUG 0-0: SM1: Addr 0x1400, Size 1024, Ctrl 0x22,
En 1

[29145.334911] EtherCAT DEBUG 0-0: Now in PREOP.

[29145.334918] EtherCAT DEBUG 0-0: Setting PDO assignment of SM2:

[29145.334919] EtherCAT DEBUG 0-0: Currently assigned PDOs: 0x1600. PDOs to
assign: 0x1600

[29145.334922] EtherCAT DEBUG 0-0: Setting number of assigned PDOs to zero.

[29145.334923] EtherCAT DEBUG 0-0: Downloading SDO 0x1C12:00.

[29145.334924] EtherCAT DEBUG: 00

[29145.334926] EtherCAT DEBUG 0-0: Expedited download request:

[29145.334927] EtherCAT DEBUG: 00 20 2F 12 1C 00 00 00 00 00

[29145.394874] EtherCAT DEBUG 0-0: Download response:

[29145.394876] EtherCAT DEBUG: 00 30 60 12 1C 00 00 00 00 00

[29145.394881] EtherCAT DEBUG 0-0: Assigning PDO 0x1600 at position 1.

[29145.394882] EtherCAT DEBUG 0-0: Downloading SDO 0x1C12:01.

[29145.394883] EtherCAT DEBUG: 00 16

[29145.394885] EtherCAT DEBUG 0-0: Expedited download request:

[29145.394885] EtherCAT DEBUG: 00 20 2B 12 1C 01 00 16 00 00

[29145.454815] EtherCAT DEBUG 0-0: Download response:

[29145.454816] EtherCAT DEBUG: 00 30 60 12 1C 01 00 16 00 00

[29145.454820] EtherCAT DEBUG 0-0: Setting number of assigned PDOs to 1.

[29145.454822] EtherCAT DEBUG 0-0: Downloading SDO 0x1C12:00.

[29145.454822] EtherCAT DEBUG: 01

[29145.454824] EtherCAT DEBUG 0-0: Expedited download request:

[29145.454824] EtherCAT DEBUG: 00 20 2F 12 1C 00 01 00 00 00

[29145.514775] EtherCAT DEBUG 0-0: Download response:

[29145.514777] EtherCAT DEBUG: 00 30 60 12 1C 00 01 00 00 00

[29145.514783] EtherCAT DEBUG 0-0: Successfully configured PDO assignment
of SM2.

[29145.514787] EtherCAT DEBUG 0-0: Setting PDO assignment of SM3:

[29145.514787] EtherCAT DEBUG 0-0: Currently assigned PDOs: 0x1A00. PDOs to
assign: 0x1A00

[29145.514790] EtherCAT DEBUG 0-0: Setting number of assigned PDOs to zero.

[29145.514792] EtherCAT DEBUG 0-0: Downloading SDO 0x1C13:00.

[29145.514792] EtherCAT DEBUG: 00

[29145.514794] EtherCAT DEBUG 0-0: Expedited download request:

[29145.514794] EtherCAT DEBUG: 00 20 2F 13 1C 00 00 00 00 00

[29145.574693] EtherCAT DEBUG 0-0: Download response:

[29145.574695] EtherCAT DEBUG: 00 30 60 13 1C 00 00 00 00 00

[29145.574700] EtherCAT DEBUG 0-0: Assigning PDO 0x1A00 at position 1.

[29145.574702] EtherCAT DEBUG 0-0: Downloading SDO 0x1C13:01.

[29145.574703] EtherCAT DEBUG: 00 1A

[29145.574704] EtherCAT DEBUG 0-0: Expedited download request:

[29145.574705] EtherCAT DEBUG: 00 20 2B 13 1C 01 00 1A 00 00

[29145.634651] EtherCAT DEBUG 0-0: Download response:

[29145.634653] EtherCAT DEBUG: 00 30 60 13 1C 01 00 1A 00 00

[29145.634656] EtherCAT DEBUG 0-0: Setting number of assigned PDOs to 1.

[29145.634658] EtherCAT DEBUG 0-0: Downloading SDO 0x1C13:00.

[29145.634659] EtherCAT DEBUG: 01

[29145.634660] EtherCAT DEBUG 0-0: Expedited download request:

[29145.634661] EtherCAT DEBUG: 00 20 2F 13 1C 00 01 00 00 00

[29145.694597] EtherCAT DEBUG 0-0: Download response:

[29145.694599] EtherCAT DEBUG: 00 30 60 13 1C 00 01 00 00 00

[29145.694603] EtherCAT DEBUG 0-0: Successfully configured PDO assignment
of SM3.

[29145.694607] EtherCAT DEBUG 0-0: SM2: Addr 0x1800, Size 19, Ctrl 0x64, En
1

[29145.694609] EtherCAT DEBUG 0-0: SM3: Addr 0x1C00, Size 15, Ctrl 0x20, En
1

[29145.714583] EtherCAT DEBUG 0 0:0: FMMU: LogAddr 0x00000000, Size 19,
PhysAddr 0x1800, SM2, Dir out

[29145.714585] EtherCAT DEBUG 0 0:0: FMMU: LogAddr 0x00000013, Size 15,
PhysAddr 0x1C00, SM3, Dir in

[29145.764458] EtherCAT 0: Domain 0: Working counter changed to 3/3.

[29145.774506] EtherCAT DEBUG 0-0: Now in SAFEOP.

[29145.814535] EtherCAT DEBUG 0-0: Now in OP. Finished configuration.

[29145.840543] EtherCAT 0: Slave states: OP.


------------------------------------------------------------------------------------------------


I guess that the pdos may be sent by master module.

but the actual value of objects in slave's object dictionary are not
changed.

what is the problem?

please do me a favor.

and this is my example code.


/*****************************************************************************
 *
 *  $Id: main.c,v 60a116ed3897 2009/07/27 10:44:16 fp $
 *
 *  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 "ecrt.h"

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

// Application parameters
#define FREQUENCY 100
#define PRIORITY 1

// Optional features
#define CONFIGURE_PDOS  1
#define SDO_ACCESS      0

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

// EtherCAT
static ec_master_t *master = NULL;
static ec_master_state_t master_state = {};

static ec_domain_t *domain0 = NULL;
static ec_domain_state_t domain_state = {};

static ec_slave_config_t *sc_epos3 = NULL;
static ec_slave_config_state_t sc_epos3_state = {};

// Timer
static unsigned int sig_alarms = 0;
static unsigned int user_alarms = 0;

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

// process data
static uint8_t *domain0_output = NULL;

#define SLAVE_DRIVE_0 0, 0
#define MAXON_EPOS3    0x000000fb, 0x64400000

// offsets for PDO entries

static unsigned int off_epos3_cntlwd;
//static unsigned int off_epos3_tvel;
static unsigned int off_epos3_tpos;
static unsigned int off_epos3_off_pos;
static unsigned int off_epos3_off_vel;
static unsigned int off_epos3_off_toq;
static unsigned int off_epos3_moo;
static unsigned int off_epos3_dof;
static unsigned int off_epos3_status;
static unsigned int off_epos3_pos_val;
static unsigned int off_epos3_vel_val;
static unsigned int off_epos3_toq_val;
static unsigned int off_epos3_mood;
static unsigned int off_epos3_dif;

const static ec_pdo_entry_reg_t domain0_regs[] = {
        {SLAVE_DRIVE_0, MAXON_EPOS3, 0x6040, 0, &off_epos3_cntlwd},
        {SLAVE_DRIVE_0, MAXON_EPOS3, 0x607a, 0, &off_epos3_tpos},
        {SLAVE_DRIVE_0, MAXON_EPOS3, 0x60b0, 0, &off_epos3_off_pos},
        {SLAVE_DRIVE_0, MAXON_EPOS3, 0x60b1, 0, &off_epos3_off_vel},
        {SLAVE_DRIVE_0, MAXON_EPOS3, 0x60b2, 0, &off_epos3_off_toq},
        {SLAVE_DRIVE_0, MAXON_EPOS3, 0x6060, 0, &off_epos3_moo},
        {SLAVE_DRIVE_0, MAXON_EPOS3, 0x2078, 1, &off_epos3_dof},
        {SLAVE_DRIVE_0, MAXON_EPOS3, 0x6041, 0, &off_epos3_status},
        {SLAVE_DRIVE_0, MAXON_EPOS3, 0x6064, 0, &off_epos3_pos_val},
        {SLAVE_DRIVE_0, MAXON_EPOS3, 0x606c, 0, &off_epos3_vel_val},
        {SLAVE_DRIVE_0, MAXON_EPOS3, 0x6077, 0, &off_epos3_toq_val},
        {SLAVE_DRIVE_0, MAXON_EPOS3, 0x6061, 0, &off_epos3_mood},
        {SLAVE_DRIVE_0, MAXON_EPOS3, 0x2071, 1, &off_epos3_dif},
        {}
};

static unsigned int counter = 0;
static unsigned int blink = 0;

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

#if CONFIGURE_PDOS

static ec_pdo_entry_info_t epos3_pdo_rx_entries[] = {
        {0x6040, 0, 16},       // controlword
        {0x607a, 0, 32},       // target position
        {0x60b0, 0, 32},       // position offset
        {0x60b1, 0, 32},       // velocity offset
        {0x60b2, 0, 16},       // torque offset
        {0x6060, 0, 8},               // modes of opeartion
        {0x2078, 1, 16}               // digital output functionality

};

static ec_pdo_entry_info_t epos3_pdo_tx_entries[] = {
        {0x6041, 0, 16},        // status word
        {0x6064, 0, 32},        // position actual value
        {0x606c, 0, 32},        // velocity actual value
        {0x6077, 0, 16},        // torque actual value
        {0x6061, 0, 8},         // modes of operation display
        {0x2071, 1, 16}         // digital input functionality
};

static ec_pdo_info_t epos3_pdos[] = {
        {0x1600, 7, epos3_pdo_rx_entries},
        {0x1a00, 6, epos3_pdo_tx_entries}
};

static ec_sync_info_t epos3_syncs[] = {
        {2, EC_DIR_OUTPUT, 1, epos3_pdos},
        {3, EC_DIR_INPUT, 1, epos3_pdos+1},
        {0xff}
};

#endif

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

#if SDO_ACCESS
static ec_sdo_request_t *sdo;
#endif

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

void check_domain_state(ec_domain_t *domain)
{
    ec_domain_state_t ds;

    ecrt_domain_state(domain, &ds);

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

    domain_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 check_slave_config_states(void)
{
    ec_slave_config_state_t s;

    ecrt_slave_config_state(sc_epos3, &s);

    if (s.al_state != sc_epos3_state.al_state)
        printf("EPOS3 slave 0 State 0x%02X.\n", s.al_state);
    if (s.online != sc_epos3_state.online)
        printf("EPOS3 slave 0: %s.\n", s.online ? "online" : "offline");
    if (s.operational != sc_epos3_state.operational)
        printf("EPOS3 slave 0: %soperational.\n",
                s.operational ? "" : "Not ");
    sc_epos3_state = s;
}

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

#if SDO_ACCESS
void read_sdo(void)
{
    switch (ecrt_sdo_request_state(sdo)) {
        case EC_REQUEST_UNUSED: // request was not used yet
            ecrt_sdo_request_read(sdo); // trigger first read
            break;
        case EC_REQUEST_BUSY:
            fprintf(stderr, "Still busy...\n");
            break;
        case EC_REQUEST_SUCCESS:
            fprintf(stderr, "SDO value: 0x%04X\n",
                    EC_READ_U16(ecrt_sdo_request_data(sdo)));
            ecrt_sdo_request_read(sdo); // trigger next read
            break;
        case EC_REQUEST_ERROR:
            fprintf(stderr, "Failed to read SDO!\n");
            ecrt_sdo_request_read(sdo); // retry reading
            break;
    }
}

#endif

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

void cyclic_task(){
        int i;

        // receive process data
        ecrt_master_receive(master);
        ecrt_domain_process(domain0);

        // check process data state (optional)
        check_domain_state(domain0);

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

               // calculate new process data
               blink = !blink;

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

               // check for islave configuration state(s) (optional)
               check_slave_config_states();

#if SDO_ACCESS
               // read process data SDO
               read_sdo();
               printf("read_sdo\n");
#endif
        }
        // read process data
        //printf(" stataus word : %u\n",EC_READ_U8(domain1_pd +
off_epos3_moo));

        // write process data
        EC_WRITE_U32(domain0_output + off_epos3_tpos, 0xff);

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


}

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

void signal_handler(int signum) {
    switch (signum) {
        case SIGALRM:
            sig_alarms++;
            break;
    }
}

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

int main(int argc, char **argv)
{
        ec_slave_config_t *sc;
        struct sigaction sa;
        struct itimerval tv;

        master = ecrt_request_master(0);
               printf("ecrt_request_master is called \n");
        if (!master)
               return -1;

        domain0 = ecrt_master_create_domain(master);
        if(!domain0)
               return -1;

        if(!(sc_epos3 = ecrt_master_slave_config(
                       master, SLAVE_DRIVE_0, MAXON_EPOS3))){
               fprintf(stderr, "Failed to get slave configuration. \n");
               return -1;
        }

        //added by kbkbc
        //if (ecrt_slave_config_sdo16(sc_epos3, 0x6040, 0x00,9 ) == 0)
               //printf("change SDO : 0x6040 \n");

#if SDO_ACCESS
    fprintf(stderr, "Creating SDO requests...\n");
    if (!(sdo = ecrt_slave_config_create_sdo_request(sc_epos3, 0x6060,
0x00, 16))) {
        fprintf(stderr, "Failed to create SDO request.\n");
        return -1;
    }
    ecrt_sdo_request_timeout(sdo, 500); // ms

#endif

#if CONFIGURE_PDOS
        printf("Configuring PDOs...\n");
        if (ecrt_slave_config_pdos(sc_epos3, EC_END, epos3_syncs)) {
               fprintf(stderr, "Failed to configure PDOs.\n");
               return -1;
        }
        printf("configureing PDO is completed!\n");
#endif
        if( ecrt_domain_reg_pdo_entry_list(domain0, domain0_regs)){
               fprintf(stderr, "PDO entty registration filed! \n");
               return -1;
        }

        printf("Activating master...\n");
        if (ecrt_master_activate(master))
               return -1;

        if( !(domain0_output = ecrt_domain_data(domain0))) {
               return -1;
        }

#if PRIORITY
    pid_t pid = getpid();
    if (setpriority(PRIO_PROCESS, pid, -19))
        fprintf(stderr, "Warning: Failed to set priority: %s\n",
                strerror(errno));
#endif

    sa.sa_handler = signal_handler;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;
    if (sigaction(SIGALRM, &sa, 0)) {
        fprintf(stderr, "Failed to install signal handler!\n");
        return -1;
    }

    printf("Starting timer...\n");
    tv.it_interval.tv_sec = 0;
    tv.it_interval.tv_usec = 1000000 / FREQUENCY;
    tv.it_value.tv_sec = 0;
    tv.it_value.tv_usec = 1000;
    if (setitimer(ITIMER_REAL, &tv, NULL)) {
        fprintf(stderr, "Failed to start timer: %s\n", strerror(errno));
        return 1;
    }

    printf("Started.\n");

    while (1) {
        pause();

        #if 0
        struct timeval t;
        gettimeofday(&t, NULL);
        printf("%u.%06u\n", t.tv_sec, t.tv_usec);
        #endif
        while (sig_alarms != user_alarms) {
            cyclic_task();
            user_alarms++;
        }
    }

    return 0;
}

/****************************************************************************/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.etherlab.org/pipermail/etherlab-dev/attachments/20121130/d7e815a7/attachment-0001.html>


More information about the etherlab-dev mailing list