diff --git a/NEWS b/NEWS index bb9ad17e948217ff254163dbb12e6f5a7812348b..623cb1a53f1eca0ab4010fda5df8e7794c521938 100644 --- a/NEWS +++ b/NEWS @@ -13,7 +13,8 @@ Changes in version 1.3.0: dynamically instead. * Added "main" and "backup" parameters to master module to hand over the MAC addresses of the devices to wait for. This made the ec_device_index - parameter of the ethernet drivers obsolete. + parameter of the ethernet drivers obsolete. The broadcast MAC address means, + that the master accepts the first device offered by any ethernet driver. * Changed format of sysconfig file and accordingly adjusted functionality of the init script to handle the above MAC address lists. * Realtime interface changes: diff --git a/TODO b/TODO index 71ef459bcd703db4344931a87c54a0b2cdf4a464..772b36e5a3d468f3dde413aafea85fcfd18aa17a 100644 --- a/TODO +++ b/TODO @@ -6,9 +6,6 @@ $Id$ ------------------------------------------------------------------------------- -* Issues for release 1.3.0: - - Take broadcast MAC address to register the first ethernet device. - * Future features: - Interface/buffers for asynchronous domain IO. - Distributed clocks. diff --git a/master/module.c b/master/module.c index bccd63b9fca0aceefab0b1986329a9393be23cb4..302fea10c70fea4174cf49141bef0f67722e196a 100644 --- a/master/module.c +++ b/master/module.c @@ -248,6 +248,19 @@ int ec_mac_is_zero(const uint8_t *mac) /*****************************************************************************/ +int ec_mac_is_broadcast(const uint8_t *mac) +{ + unsigned int i; + + for (i = 0; i < ETH_ALEN; i++) + if (mac[i] != 0xff) + return 0; + + return 1; +} + +/*****************************************************************************/ + static int ec_mac_parse(uint8_t *mac, const char *src, int allow_empty) { unsigned int i, value; @@ -400,19 +413,19 @@ int ecdev_offer(struct net_device *net_dev, /**< net_device to offer */ for (i = 0; i < master_count; i++) { master = &masters[i]; - if (ec_mac_equal(master->main_mac, net_dev->dev_addr)) { - ec_mac_print(master->main_mac, 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", str, master->index); - down(&master->device_sem); - if (master->main_device.dev) { - EC_ERR("Master %u already has a device attached.\n", - master->index); - up(&master->device_sem); - return -1; - } - ec_device_attach(&master->main_device, net_dev, poll, module); up(&master->device_sem); @@ -420,9 +433,13 @@ int ecdev_offer(struct net_device *net_dev, /**< net_device to offer */ *ecdev = &master->main_device; // offer accepted return 0; // no error } - else if (master->debug_level) { - ec_mac_print(master->main_mac, str); - EC_DBG("Master %u declined device %s.\n", master->index, str); + else { + up(&master->device_sem); + + if (master->debug_level) { + ec_mac_print(net_dev->dev_addr, str); + EC_DBG("Master %u declined device %s.\n", master->index, str); + } } } @@ -446,8 +463,7 @@ void ecdev_withdraw(ec_device_t *device /**< EtherCAT device */) ec_master_t *master = device->master; char str[20]; - ec_mac_print(master->main_mac, str); - + ec_mac_print(device->dev->dev_addr, str); EC_INFO("Master %u releasing main device %s.\n", master->index, str); down(&master->device_sem); diff --git a/script/sysconfig/ethercat b/script/sysconfig/ethercat index c8ba12958523ea1d98124242626a5c061421337c..2ab96292d6d5805203deca789692d19d4a6574fc 100644 --- a/script/sysconfig/ethercat +++ b/script/sysconfig/ethercat @@ -16,6 +16,9 @@ # Specify the MAC address (hexadecimal with colons) of the Ethernet device to # use. Example: "00:00:08:44:ab:66" # +# The broadcast address "ff:ff:ff:ff:ff:ff" has a special meaning: It tells +# the master to accept the first device offered by any ethernet driver. +# # The MASTER<X>_DEVICE variables also determine, how many masters will be # created: A non-empty variable MASTER0_DEVICE will create one master, adding # a non-empty variable MASTER1_DEVICE will create a second master, and so on.