Master accepting two devices.
--- 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");
+ }
}
/*****************************************************************************/
--- 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);
}
}
--- 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<X>_DEVICE variable specifies the Ethernet device for a master
# with index 'X'.
@@ -26,6 +28,15 @@
#MASTER1_DEVICE=""
#
+# Backup Ethernet devices
+#
+# The MASTER<X>_BACKUP variables specify the devices used for redundancy. They
+# behaves nearly the same as the MASTER<X>_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
--- 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 << "???";