Master accepting two devices.

This commit is contained in:
Florian Pose 2011-11-09 12:05:44 +01:00
parent 19675f0229
commit ec84b03034
4 changed files with 71 additions and 30 deletions

View File

@ -496,10 +496,21 @@ void ec_device_poll(
void ecdev_withdraw(ec_device_t *device /**< EtherCAT device */)
{
ec_master_t *master = device->master;
char str[20];
char dev_str[20], mac_str[20];
ec_mac_print(device->dev->dev_addr, str);
EC_MASTER_INFO(master, "Releasing main device %s.\n", str);
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 @@ void ecdev_withdraw(ec_device_t *device /**< EtherCAT device */)
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 @@ int ecdev_open(ec_device_t *device /**< EtherCAT device */)
*/
void ecdev_close(ec_device_t *device /**< EtherCAT device */)
{
ec_master_leave_idle_phase(device->master);
ec_master_t *master = device->master;
if (ec_device_close(device))
EC_MASTER_WARN(device->master, "Failed to close device!\n");
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");
}
}
/*****************************************************************************/

View File

@ -467,34 +467,43 @@ ec_device_t *ecdev_offer(
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);
}
}

View File

@ -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'.
@ -25,6 +27,15 @@
MASTER0_DEVICE=""
#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.
#

View File

@ -93,7 +93,7 @@ void CommandMaster::execute(const StringVector &args)
<< " 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 << "???";