Hello Florian,
Saw the post on vma fault...I had just mentioned it since it concerned me.
If you're not worried, nether am I... ;)
As to re-organizing the code as you suggest, it works fine now! I added
some diagnostics to count how many cycles it takes for the slaves to go to
OP, and it looks like somewhere between 25 and 100, depending on how fast
you run the transactions, which is something I can easily live with by
guarding my application from trying to do things until all slaves are
detected in OP.
I attach my test app for anyone else on the list who might find it useful.
Thanks again for your help!
Regards,
Dusty Clark
MMT Observatory
University of Arizona
> Hi dusty,
>
> On Wed, Mar 17, 2010 at 04:36:13PM -0700, [email protected] wrote:
>> EtherCAT DEBUG: mmap()
>> EtherCAT DEBUG: Vma fault, virtual_address = b7838000, offset = 0, page
>> =
>> c18913e0 ?? Why is there a fault reported here ??
>
> see my prior post.
>
>> printf("Activating master...");
>> if (ecrt_master_activate(master)) {
>> fprintf(stderr,"activation failed.\n");
>> return -1;
>> }
>> printf("ok!\n");
>>
>> if (!(domain1_pd = ecrt_domain_data(domain1))) {
>> fprintf(stderr,"Domain data initialization failed.\n");
>> return -1;
>> }
>> printf("Domain data registered ok.\n");
>>
>> sc_dig_out = ecrt_master_slave_config(
>> master, DigOutSlavePos, Beckhoff_EL2004);
>>
>> sc_dig_in = ecrt_master_slave_config(
>> master, DigInSlavePos, Beckhoff_EL1014);
>
> BTW, you should not add further slave configuration after calling
> ecrt_master_activate(). They will not have any chance to participate on
> process data exchange. But that's not the problem here.
>
>> check_master_state();
>> check_domain1_state();
>>
>> #if 1
>> for (j=0;j<2;j++)
>> {
>> ecrt_master_receive(master);
>> ecrt_domain_process(domain1);
>> check_slave_config_states();
>> sleep(1);
>
> You are sending one frame per second. The master state machine needs
> many cycles to configure the whole bus, you're giving it no change to
> configure the slaves (only 2 cycles). Moreover most slaves have a
> process data watchdog of approx. 100 ms.
>
> --
> Best regards,
> Florian Pose
>
> http://etherlab.org
> _______________________________________________
> etherlab-users mailing list
> [email protected]
> http://lists.etherlab.org/mailman/listinfo/etherlab-users
>
--
/*****************************************************************************
*
* $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 <stdio.h>
#include <unistd.h>
/****************************************************************************/
//EtherCAT
#include "ecrt.h"
/****************************************************************************/
// Optional features
#define PRECONFIGURE_PDOS 1 //use configuration in build
#define CONFIGURE_PDOS 0 //configure at run-time
/****************************************************************************/
// 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 ec_slave_config_t *sc_dig_out = NULL;
static ec_slave_config_t *sc_dig_in = NULL;
/****************************************************************************/
#define NUMSLAVES 2
// process data
static uint8_t *domain1_pd = NULL;
//definitions for the bus connections and expected slave positions
#define BusCouplerPos 0, 0
#define DigOutSlavePos 0, 1
#define DigInSlavePos 0, 2
#define Beckhoff_EK1100 0x00000002, 0x044c2c52
#define Beckhoff_EL2004 0x00000002, 0x07d43052
#define Beckhoff_EL1014 0x00000002, 0x03f63052
// offsets for PDO entries
static unsigned int off_dig_out;
static unsigned int off_dig_in;
const static ec_pdo_entry_reg_t domain1_regs[] = {
{DigOutSlavePos, Beckhoff_EL2004, 0x7000, 1, &off_dig_out},
{DigInSlavePos, Beckhoff_EL1014, 0x6000, 1, &off_dig_in},
{}
};
static char slaves_up = 0;
/*****************************************************************************/
#if PRECONFIGURE_PDOS
/* Master 0, Slave 1, "EL2004"
* Vendor ID: 0x00000002
* Product code: 0x07d43052
* Revision number: 0x00100000
*/
ec_pdo_entry_info_t EL2004_pdo_entries[] = {
{0x7000, 0x01, 1}, /* Output */
{0x7010, 0x01, 1}, /* Output */
{0x7020, 0x01, 1}, /* Output */
{0x7030, 0x01, 1}, /* Output */
};
ec_pdo_info_t EL2004_pdos[] = {
{0x1600, 1, EL2004_pdo_entries + 0}, /* Channel 1 */
{0x1601, 1, EL2004_pdo_entries + 1}, /* Channel 2 */
{0x1602, 1, EL2004_pdo_entries + 2}, /* Channel 3 */
{0x1603, 1, EL2004_pdo_entries + 3}, /* Channel 4 */
};
ec_sync_info_t EL2004_syncs[] = {
{0, EC_DIR_OUTPUT, 4, EL2004_pdos + 0, EC_WD_ENABLE},
{0xff}
};
/* Master 0, Slave 2, "EL1014"
* Vendor ID: 0x00000002
* Product code: 0x03f63052
* Revision number: 0x00100000
*/
ec_pdo_entry_info_t EL1014_pdo_entries[] = {
{0x6000, 0x01, 1}, /* Input */
{0x6010, 0x01, 1}, /* Input */
{0x6020, 0x01, 1}, /* Input */
{0x6030, 0x01, 1}, /* Input */
};
ec_pdo_info_t EL1014_pdos[] = {
{0x1a00, 1, EL1014_pdo_entries + 0}, /* Channel 1 */
{0x1a01, 1, EL1014_pdo_entries + 1}, /* Channel 2 */
{0x1a02, 1, EL1014_pdo_entries + 2}, /* Channel 3 */
{0x1a03, 1, EL1014_pdo_entries + 3}, /* Channel 4 */
};
ec_sync_info_t EL1014_syncs[] = {
{0, EC_DIR_INPUT, 4, EL1014_pdos + 0, EC_WD_DISABLE},
{0xff}
};
#endif
/*****************************************************************************/
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 check_slave_config_states()
{
ec_slave_config_state_t s;
ecrt_slave_config_state(sc_dig_out, &s);
if (slaves_up < 1 && s.al_state != 0x08) {
printf("DigOut: State 0x%02X.\n", s.al_state);
}
if (slaves_up < 1 && s.al_state == 0x08) {
slaves_up = 1;
}
ecrt_slave_config_state(sc_dig_in, &s);
if (slaves_up < 2 && s.al_state != 0x08) {
printf("DigIn: State 0x%02X.\n", s.al_state);
}
if (slaves_up < 2 && s.al_state == 0x08) {
slaves_up = 2;
}
}
/*****************************************************************************/
int main(void) //(int argc, char **argv)
{
unsigned int j, in, out, op_flag;
ec_slave_config_t *sc;
ec_master_state_t ms;
master = ecrt_request_master(0);
if (!master)
{ fprintf(stderr, "Unable to get requested master.\n");
return -1;
}
domain1 = ecrt_master_create_domain(master);
if (!domain1)
{ fprintf(stderr, "Unable to create process data domain.\n");
return -1;
}
#if CONFIGURE_PDOS
printf("Configuring PDOs...\n");
if (!(sc = ecrt_master_slave_config(
master, DigOutSlavePos, Beckhoff_EL2004))) {
fprintf(stderr, "Failed to get EL2004 configuration.\n");
return -1;
}
if (!(sc = ecrt_master_slave_config(
master, DigInSlavePos, Beckhoff_EL1014))) {
fprintf(stderr, "Failed to get EL1014 configuration.\n");
return -1;
}
#endif
// Create configuration for the bus coupler
sc = ecrt_master_slave_config(master, BusCouplerPos, Beckhoff_EK1100);
if (!sc) {
fprintf(stderr, "Failed to get EK1100 configuration.\n");
return -1;
}
sc_dig_out = ecrt_master_slave_config(
master, DigOutSlavePos, Beckhoff_EL2004);
sc_dig_in = ecrt_master_slave_config(
master, DigInSlavePos, Beckhoff_EL1014);
if (ecrt_domain_reg_pdo_entry_list(domain1, domain1_regs)) {
fprintf(stderr, "PDO entry registration failed!\n");
return -1;
}
printf("Activating master...");
if (ecrt_master_activate(master)) {
fprintf(stderr,"activation failed.\n");
return -1;
}
printf("ok!\n");
if (!(domain1_pd = ecrt_domain_data(domain1))) {
fprintf(stderr,"Domain data initialization failed.\n");
return -1;
}
printf("Domain data registered ok.\n");
check_master_state();
check_domain1_state();
in = 0; out = 0; op_flag = 0;
#if 1
for (j=0;j<30000;j++)
{
ecrt_master_receive(master);
ecrt_domain_process(domain1);
check_slave_config_states();
if (slaves_up == 2 && !op_flag) {
printf("All slaves reached OP state at %d cycles.\n", j);
op_flag = 1;
}
usleep(1000);
in = EC_READ_U8(domain1_pd + off_dig_in) & 0x0F;
if (in != out) {
EC_WRITE_U8(domain1_pd + off_dig_out, in);
out = in;
printf("Input data is now: %x\n", in);
}
// send process data
ecrt_domain_queue(domain1);
ecrt_master_send(master);
}
//dummy to keep abrt from seeing the last datagram (which won't match)
ecrt_master_receive(master);
ecrt_domain_process(domain1);
#endif
printf("...Done. Releasing the master!\n");
ecrt_release_master(master);
return 0;
}
/****************************************************************************/_______________________________________________
etherlab-users mailing list
[email protected]
http://lists.etherlab.org/mailman/listinfo/etherlab-users