# HG changeset patch # User Florian Pose # Date 1320836744 -3600 # Node ID 71425e6120d85352d2550b07c230e32ef6a7b5fe # Parent 26c74f035ab0b9250b99439345711d6f563e3922 Master accepting two devices. diff -r 26c74f035ab0 -r 71425e6120d8 master/device.c --- a/master/device.c Wed Nov 09 09:55:58 2011 +0100 +++ b/master/device.c Wed Nov 09 12:05:44 2011 +0100 @@ -496,10 +496,21 @@ void ecdev_withdraw(ec_device_t *device /**< EtherCAT device */) { ec_master_t *master = device->master; - char str[20]; - - ec_mac_print(device->dev->dev_addr, str); - EC_MASTER_INFO(master, "Releasing main device %s.\n", str); + char dev_str[20], mac_str[20]; + + ec_mac_print(device->dev->dev_addr, mac_str); + + if (device == &master->main_device) { + sprintf(dev_str, "main"); + } else if (device == &master->backup_device) { + sprintf(dev_str, "backup"); + } else { + EC_MASTER_WARN(master, "%s() called with unknown device %s!\n", + __func__, mac_str); + sprintf(dev_str, "UNKNOWN"); + } + + EC_MASTER_INFO(master, "Releasing %s device %s.\n", dev_str, mac_str); down(&master->device_sem); ec_device_detach(device); @@ -516,17 +527,22 @@ int ecdev_open(ec_device_t *device /**< EtherCAT device */) { int ret; + ec_master_t *master = device->master; ret = ec_device_open(device); if (ret) { - EC_MASTER_ERR(device->master, "Failed to open device!\n"); + EC_MASTER_ERR(master, "Failed to open device!\n"); return ret; } - ret = ec_master_enter_idle_phase(device->master); - if (ret) { - EC_MASTER_ERR(device->master, "Failed to enter IDLE phase!\n"); - return ret; + if (master->main_device.open && + (ec_mac_is_zero(master->backup_mac) || + master->backup_device.open)) { + ret = ec_master_enter_idle_phase(device->master); + if (ret) { + EC_MASTER_ERR(device->master, "Failed to enter IDLE phase!\n"); + return ret; + } } return 0; @@ -541,10 +557,15 @@ */ void ecdev_close(ec_device_t *device /**< EtherCAT device */) { - ec_master_leave_idle_phase(device->master); - - if (ec_device_close(device)) - EC_MASTER_WARN(device->master, "Failed to close device!\n"); + ec_master_t *master = device->master; + + if (master->phase == EC_IDLE) { + ec_master_leave_idle_phase(master); + } + + if (ec_device_close(device)) { + EC_MASTER_WARN(master, "Failed to close device!\n"); + } } /*****************************************************************************/ diff -r 26c74f035ab0 -r 71425e6120d8 master/module.c --- a/master/module.c Wed Nov 09 09:55:58 2011 +0100 +++ b/master/module.c Wed Nov 09 12:05:44 2011 +0100 @@ -467,34 +467,43 @@ for (i = 0; i < master_count; i++) { master = &masters[i]; + ec_mac_print(net_dev->dev_addr, str); down(&master->device_sem); - if (master->main_device.dev) { // master already has a device - up(&master->device_sem); - continue; - } - - if (ec_mac_equal(master->main_mac, net_dev->dev_addr) - || ec_mac_is_broadcast(master->main_mac)) { - ec_mac_print(net_dev->dev_addr, str); - EC_INFO("Accepting device %s for master %u.\n", + + if (!master->main_device.dev + && (ec_mac_equal(master->main_mac, net_dev->dev_addr) + || ec_mac_is_broadcast(master->main_mac))) { + + EC_INFO("Accepting %s as main device for master %u.\n", str, master->index); ec_device_attach(&master->main_device, net_dev, poll, module); up(&master->device_sem); - + snprintf(net_dev->name, IFNAMSIZ, "ec%u", master->index); return &master->main_device; // offer accepted - } - else { + + } else if (!master->backup_device.dev + && ec_mac_equal(master->backup_mac, net_dev->dev_addr)) { + + EC_INFO("Accepting %s as backup device for master %u.\n", + str, master->index); + + ec_device_attach(&master->backup_device, net_dev, poll, + module); up(&master->device_sem); - if (master->debug_level) { - ec_mac_print(net_dev->dev_addr, str); - EC_MASTER_DBG(master, 0, "Master declined device %s.\n", - str); - } + snprintf(net_dev->name, IFNAMSIZ, "ecb%u", master->index); + + return &master->backup_device; // offer accepted + + } else { + + up(&master->device_sem); + + EC_MASTER_DBG(master, 1, "Master declined device %s.\n", str); } } diff -r 26c74f035ab0 -r 71425e6120d8 script/sysconfig/ethercat --- a/script/sysconfig/ethercat Wed Nov 09 09:55:58 2011 +0100 +++ b/script/sysconfig/ethercat Wed Nov 09 12:05:44 2011 +0100 @@ -4,10 +4,12 @@ # # $Id$ # +# vim: spelllang=en spell tw=78 +# #------------------------------------------------------------------------------ # -# Master devices. +# Main Ethernet devices. # # The MASTER_DEVICE variable specifies the Ethernet device for a master # with index 'X'. @@ -26,6 +28,15 @@ #MASTER1_DEVICE="" # +# Backup Ethernet devices +# +# The MASTER_BACKUP variables specify the devices used for redundancy. They +# behaves nearly the same as the MASTER_DEVICE variable, except that it +# does not interpret the ff:ff:ff:ff:ff:ff address. +# +#MASTER0_BACKUP="" + +# # Ethernet driver modules to use for EtherCAT operation. # # Specify a non-empty list of Ethernet drivers, that shall be used for EtherCAT diff -r 26c74f035ab0 -r 71425e6120d8 tool/CommandMaster.cpp --- a/tool/CommandMaster.cpp Wed Nov 09 09:55:58 2011 +0100 +++ b/tool/CommandMaster.cpp Wed Nov 09 12:05:44 2011 +0100 @@ -93,7 +93,7 @@ << " Phase: "; switch (data.phase) { - case 0: cout << "Waiting for device..."; break; + case 0: cout << "Waiting for device(s)..."; break; case 1: cout << "Idle"; break; case 2: cout << "Operation"; break; default: cout << "???";