Added the new ethercat comman-line tool with lsec functionality.
This commit is contained in:
parent
9f0555ee26
commit
3b4cae9626
15
Makefile.am
15
Makefile.am
|
|
@ -31,9 +31,20 @@
|
||||||
#
|
#
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
SUBDIRS = master devices script include
|
SUBDIRS = \
|
||||||
|
devices \
|
||||||
|
include \
|
||||||
|
master \
|
||||||
|
script \
|
||||||
|
tools
|
||||||
|
|
||||||
DIST_SUBDIRS = master devices script include examples
|
DIST_SUBDIRS = \
|
||||||
|
devices \
|
||||||
|
examples \
|
||||||
|
include \
|
||||||
|
master \
|
||||||
|
script \
|
||||||
|
tools
|
||||||
|
|
||||||
EXTRA_DIST = \
|
EXTRA_DIST = \
|
||||||
Doxyfile \
|
Doxyfile \
|
||||||
|
|
|
||||||
3
NEWS
3
NEWS
|
|
@ -49,6 +49,8 @@ Changes in version 1.4.0:
|
||||||
- Exported ecrt_slave_config_sdo(), the generic Sdo configuration
|
- Exported ecrt_slave_config_sdo(), the generic Sdo configuration
|
||||||
function.
|
function.
|
||||||
- Removed the bus_state and bus_tainted flags from ec_master_state_t.
|
- Removed the bus_state and bus_tainted flags from ec_master_state_t.
|
||||||
|
* Replaces the Sysfs interface with a new 'ethercat' command-line tool. See
|
||||||
|
'ethercat --help'.
|
||||||
* Removed include/ecdb.h.
|
* Removed include/ecdb.h.
|
||||||
* Sdo dictionaries will now also be fetched in operation mode.
|
* Sdo dictionaries will now also be fetched in operation mode.
|
||||||
* SII write requests will now also be processed in operation mode.
|
* SII write requests will now also be processed in operation mode.
|
||||||
|
|
@ -58,6 +60,7 @@ Changes in version 1.4.0:
|
||||||
* Network driver news:
|
* Network driver news:
|
||||||
- Added 8139too driver for kernel 2.6.22, thanks to Erwin Burgstaller.
|
- Added 8139too driver for kernel 2.6.22, thanks to Erwin Burgstaller.
|
||||||
- Added 8139too driver for kernel 2.6.23, thanks to Richard Hacker.
|
- Added 8139too driver for kernel 2.6.23, thanks to Richard Hacker.
|
||||||
|
- Added 8139too driver for kernel 2.6.24.
|
||||||
- Added e1000 driver for kernel 2.6.22.
|
- Added e1000 driver for kernel 2.6.22.
|
||||||
- Added e1000 driver for kernel 2.6.24, thanks to Matthias Luescher.
|
- Added e1000 driver for kernel 2.6.24, thanks to Matthias Luescher.
|
||||||
- Added alpha support for the Reaktek r8169 chipset, thanks to Scott
|
- Added alpha support for the Reaktek r8169 chipset, thanks to Scott
|
||||||
|
|
|
||||||
3
TODO
3
TODO
|
|
@ -8,8 +8,7 @@ $Id$
|
||||||
|
|
||||||
Version 1.4.0:
|
Version 1.4.0:
|
||||||
|
|
||||||
* Replace Sysfs interface with cdev and a user space program
|
* Replace all Sysfs files via the new ethercat tool.
|
||||||
to replace lsec; move a few sysfs attributes to proc.
|
|
||||||
* Remove the end state of the master state machine.
|
* Remove the end state of the master state machine.
|
||||||
* Supply new ec_master_state_t.
|
* Supply new ec_master_state_t.
|
||||||
* Implement ecrt_slave_config_state().
|
* Implement ecrt_slave_config_state().
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,8 @@ branch=trunk
|
||||||
AC_DEFINE_UNQUOTED(BRANCH, ["$branch"], [Subversion branch])
|
AC_DEFINE_UNQUOTED(BRANCH, ["$branch"], [Subversion branch])
|
||||||
AC_SUBST(BRANCH, [$branch])
|
AC_SUBST(BRANCH, [$branch])
|
||||||
|
|
||||||
|
AC_PROG_CXX
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
# Linux sources
|
# Linux sources
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
|
|
@ -510,6 +512,7 @@ AC_CONFIG_FILES([
|
||||||
script/Makefile
|
script/Makefile
|
||||||
script/init.d/Makefile
|
script/init.d/Makefile
|
||||||
script/sysconfig/Makefile
|
script/sysconfig/Makefile
|
||||||
|
tools/Makefile
|
||||||
])
|
])
|
||||||
AC_OUTPUT
|
AC_OUTPUT
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@
|
||||||
obj-m := ec_master.o
|
obj-m := ec_master.o
|
||||||
|
|
||||||
ec_master-objs := \
|
ec_master-objs := \
|
||||||
|
cdev.o \
|
||||||
datagram.o \
|
datagram.o \
|
||||||
device.o \
|
device.o \
|
||||||
domain.o \
|
domain.o \
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@
|
||||||
|
|
||||||
EXTRA_DIST = \
|
EXTRA_DIST = \
|
||||||
Kbuild.in \
|
Kbuild.in \
|
||||||
|
cdev.c cdev.h \
|
||||||
datagram.c datagram.h \
|
datagram.c datagram.h \
|
||||||
debug.c debug.h \
|
debug.c debug.h \
|
||||||
device.c device.h \
|
device.c device.h \
|
||||||
|
|
@ -50,6 +51,7 @@ EXTRA_DIST = \
|
||||||
fsm_slave_config.c fsm_slave_config.h \
|
fsm_slave_config.c fsm_slave_config.h \
|
||||||
fsm_slave_scan.c fsm_slave_scan.h \
|
fsm_slave_scan.c fsm_slave_scan.h \
|
||||||
globals.h \
|
globals.h \
|
||||||
|
ioctl.h \
|
||||||
mailbox.c mailbox.h \
|
mailbox.c mailbox.h \
|
||||||
master.c master.h \
|
master.c master.h \
|
||||||
module.c \
|
module.c \
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,204 @@
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 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
|
||||||
|
* as published by the Free Software Foundation; either version 2 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* 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 right to use EtherCAT Technology is granted and comes free of
|
||||||
|
* charge under condition of compatibility of product made by
|
||||||
|
* Licensee. People intending to distribute/sell products based on the
|
||||||
|
* code, have to sign an agreement to guarantee that products using
|
||||||
|
* software based on IgH EtherCAT master stay compatible with the actual
|
||||||
|
* EtherCAT specification (which are released themselves as an open
|
||||||
|
* standard) as the (only) precondition to have the right to use EtherCAT
|
||||||
|
* Technology, IP and trade marks.
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
\file
|
||||||
|
EtherCAT master character device.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
#include <linux/module.h>
|
||||||
|
|
||||||
|
#include "cdev.h"
|
||||||
|
#include "master.h"
|
||||||
|
#include "ioctl.h"
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
/** \cond */
|
||||||
|
|
||||||
|
int eccdev_open(struct inode *, struct file *);
|
||||||
|
int eccdev_release(struct inode *, struct file *);
|
||||||
|
ssize_t eccdev_read(struct file *, char __user *, size_t, loff_t *);
|
||||||
|
ssize_t eccdev_write(struct file *, const char __user *, size_t, loff_t *);
|
||||||
|
int eccdev_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
static struct file_operations eccdev_fops = {
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
.open = eccdev_open,
|
||||||
|
.release = eccdev_release,
|
||||||
|
.ioctl = eccdev_ioctl
|
||||||
|
};
|
||||||
|
|
||||||
|
/** \endcond */
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
/** Constructor.
|
||||||
|
*
|
||||||
|
* \return 0 in case of success, else < 0
|
||||||
|
*/
|
||||||
|
int ec_cdev_init(
|
||||||
|
ec_cdev_t *cdev, /**< EtherCAT master character device. */
|
||||||
|
ec_master_t *master, /**< Parent master. */
|
||||||
|
dev_t dev_num /**< Device number. */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
cdev->master = master;
|
||||||
|
|
||||||
|
cdev_init(&cdev->cdev, &eccdev_fops);
|
||||||
|
cdev->cdev.owner = THIS_MODULE;
|
||||||
|
|
||||||
|
if (cdev_add(&cdev->cdev,
|
||||||
|
MKDEV(MAJOR(dev_num), master->index), 1)) {
|
||||||
|
EC_ERR("Failed to add character device!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
/** Destructor.
|
||||||
|
*/
|
||||||
|
void ec_cdev_clear(ec_cdev_t *cdev /**< EtherCAT XML device */)
|
||||||
|
{
|
||||||
|
cdev_del(&cdev->cdev);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* File operations
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
int eccdev_open(struct inode *inode, struct file *filp)
|
||||||
|
{
|
||||||
|
ec_cdev_t *cdev = container_of(inode->i_cdev, ec_cdev_t, cdev);
|
||||||
|
|
||||||
|
filp->private_data = cdev;
|
||||||
|
EC_DBG("File opened.\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
int eccdev_release(struct inode *inode, struct file *filp)
|
||||||
|
{
|
||||||
|
//ec_cdev_t *cdev = container_of(inode->i_cdev, ec_cdev_t, cdev);
|
||||||
|
|
||||||
|
EC_DBG("File closed.\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
int eccdev_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||||
|
unsigned long arg)
|
||||||
|
{
|
||||||
|
ec_cdev_t *cdev = container_of(inode->i_cdev, ec_cdev_t, cdev);
|
||||||
|
ec_master_t *master = cdev->master;
|
||||||
|
|
||||||
|
if (master->debug_level)
|
||||||
|
EC_DBG("ioctl(inode = %x, filp = %x, cmd = %u, arg = %u)\n",
|
||||||
|
(u32) inode, (u32) filp, (u32) cmd, (u32) arg);
|
||||||
|
|
||||||
|
switch (cmd) {
|
||||||
|
case EC_IOCTL_SLAVE_COUNT:
|
||||||
|
{
|
||||||
|
unsigned int slave_count = master->slave_count;
|
||||||
|
EC_INFO("EC_IOCTL_SLAVE_COUNT\n");
|
||||||
|
if (!arg)
|
||||||
|
return -EFAULT;
|
||||||
|
if (copy_to_user((void __user *) arg, &slave_count,
|
||||||
|
sizeof(unsigned int)))
|
||||||
|
return -EFAULT;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
case EC_IOCTL_SLAVE_INFO:
|
||||||
|
{
|
||||||
|
struct ec_ioctl_slave_info *infos, *info;
|
||||||
|
unsigned int slave_count = master->slave_count;
|
||||||
|
const ec_slave_t *slave;
|
||||||
|
unsigned int i = 0;
|
||||||
|
|
||||||
|
if (master->debug_level)
|
||||||
|
EC_DBG("EC_IOCTL_SLAVE_INFOS\n");
|
||||||
|
|
||||||
|
if (!slave_count)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!arg)
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
if (!(infos = kmalloc(slave_count *
|
||||||
|
sizeof(struct ec_ioctl_slave_info),
|
||||||
|
GFP_KERNEL)))
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
list_for_each_entry(slave, &master->slaves, list) {
|
||||||
|
info = &infos[i++];
|
||||||
|
info->vendor_id = slave->sii.vendor_id;
|
||||||
|
info->product_code = slave->sii.product_code;
|
||||||
|
info->alias = slave->sii.alias;
|
||||||
|
info->ring_position = slave->ring_position;
|
||||||
|
info->state = slave->current_state;
|
||||||
|
if (slave->sii.name) {
|
||||||
|
strncpy(info->description, slave->sii.name,
|
||||||
|
EC_IOCTL_SLAVE_INFO_DESC_SIZE);
|
||||||
|
info->description[EC_IOCTL_SLAVE_INFO_DESC_SIZE - 1]
|
||||||
|
= 0;
|
||||||
|
} else {
|
||||||
|
info->description[0] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (copy_to_user((void __user *) arg, infos, slave_count *
|
||||||
|
sizeof(struct ec_ioctl_slave_info))) {
|
||||||
|
kfree(infos);
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
kfree(infos);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return -ENOIOCTLCMD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 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
|
||||||
|
* as published by the Free Software Foundation; either version 2 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* 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 right to use EtherCAT Technology is granted and comes free of
|
||||||
|
* charge under condition of compatibility of product made by
|
||||||
|
* Licensee. People intending to distribute/sell products based on the
|
||||||
|
* code, have to sign an agreement to guarantee that products using
|
||||||
|
* software based on IgH EtherCAT master stay compatible with the actual
|
||||||
|
* EtherCAT specification (which are released themselves as an open
|
||||||
|
* standard) as the (only) precondition to have the right to use EtherCAT
|
||||||
|
* Technology, IP and trade marks.
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
\file
|
||||||
|
EtherCAT master character device.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __EC_CDEV_H__
|
||||||
|
#define __EC_CDEV_H__
|
||||||
|
|
||||||
|
#include <linux/fs.h>
|
||||||
|
#include <linux/cdev.h>
|
||||||
|
|
||||||
|
#include "globals.h"
|
||||||
|
#include "../include/ecrt.h"
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
/** EtherCAT master character device.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
ec_master_t *master; /**< Master owning the device. */
|
||||||
|
struct cdev cdev; /**< Character device. */
|
||||||
|
} ec_cdev_t;
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
int ec_cdev_init(ec_cdev_t *, ec_master_t *, dev_t);
|
||||||
|
void ec_cdev_clear(ec_cdev_t *);
|
||||||
|
|
||||||
|
int ec_cdev_request(ec_cdev_t *, uint32_t, uint32_t);
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 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
|
||||||
|
* as published by the Free Software Foundation; either version 2 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* 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 right to use EtherCAT Technology is granted and comes free of
|
||||||
|
* charge under condition of compatibility of product made by
|
||||||
|
* Licensee. People intending to distribute/sell products based on the
|
||||||
|
* code, have to sign an agreement to guarantee that products using
|
||||||
|
* software based on IgH EtherCAT master stay compatible with the actual
|
||||||
|
* EtherCAT specification (which are released themselves as an open
|
||||||
|
* standard) as the (only) precondition to have the right to use EtherCAT
|
||||||
|
* Technology, IP and trade marks.
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
\file
|
||||||
|
EtherCAT master character device IOCTL commands.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __EC_IOCTL_H__
|
||||||
|
#define __EC_IOCTL_H__
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
enum {
|
||||||
|
EC_IOCTL_SLAVE_COUNT = 0,
|
||||||
|
EC_IOCTL_SLAVE_INFO,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
#define EC_IOCTL_SLAVE_INFO_DESC_SIZE 243
|
||||||
|
|
||||||
|
struct ec_ioctl_slave_info {
|
||||||
|
uint32_t vendor_id;
|
||||||
|
uint32_t product_code;
|
||||||
|
uint16_t alias;
|
||||||
|
uint16_t ring_position;
|
||||||
|
uint8_t state;
|
||||||
|
char description[EC_IOCTL_SLAVE_INFO_DESC_SIZE];
|
||||||
|
};
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -105,7 +105,8 @@ int ec_master_init(ec_master_t *master, /**< EtherCAT master */
|
||||||
struct kobject *module_kobj, /**< kobject of the master module */
|
struct kobject *module_kobj, /**< kobject of the master module */
|
||||||
unsigned int index, /**< master index */
|
unsigned int index, /**< master index */
|
||||||
const uint8_t *main_mac, /**< MAC address of main device */
|
const uint8_t *main_mac, /**< MAC address of main device */
|
||||||
const uint8_t *backup_mac /**< MAC address of backup device */
|
const uint8_t *backup_mac, /**< MAC address of backup device */
|
||||||
|
dev_t device_number /**< Character device number. */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
@ -178,9 +179,13 @@ int ec_master_init(ec_master_t *master, /**< EtherCAT master */
|
||||||
init_MUTEX(&master->sdo_sem);
|
init_MUTEX(&master->sdo_sem);
|
||||||
init_waitqueue_head(&master->sdo_queue);
|
init_waitqueue_head(&master->sdo_queue);
|
||||||
|
|
||||||
|
// init character device
|
||||||
|
if (ec_cdev_init(&master->cdev, master, device_number))
|
||||||
|
goto out_return;
|
||||||
|
|
||||||
// init devices
|
// init devices
|
||||||
if (ec_device_init(&master->main_device, master))
|
if (ec_device_init(&master->main_device, master))
|
||||||
goto out_return;
|
goto out_cdev;
|
||||||
|
|
||||||
if (ec_device_init(&master->backup_device, master))
|
if (ec_device_init(&master->backup_device, master))
|
||||||
goto out_clear_main;
|
goto out_clear_main;
|
||||||
|
|
@ -222,6 +227,8 @@ out_clear_backup:
|
||||||
ec_device_clear(&master->backup_device);
|
ec_device_clear(&master->backup_device);
|
||||||
out_clear_main:
|
out_clear_main:
|
||||||
ec_device_clear(&master->main_device);
|
ec_device_clear(&master->main_device);
|
||||||
|
out_cdev:
|
||||||
|
ec_cdev_clear(&master->cdev);
|
||||||
out_return:
|
out_return:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -248,6 +255,7 @@ void ec_master_clear(
|
||||||
ec_datagram_clear(&master->fsm_datagram);
|
ec_datagram_clear(&master->fsm_datagram);
|
||||||
ec_device_clear(&master->backup_device);
|
ec_device_clear(&master->backup_device);
|
||||||
ec_device_clear(&master->main_device);
|
ec_device_clear(&master->main_device);
|
||||||
|
ec_cdev_clear(&master->cdev);
|
||||||
|
|
||||||
// destroy self
|
// destroy self
|
||||||
kobject_del(&master->kobj);
|
kobject_del(&master->kobj);
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
#include "domain.h"
|
#include "domain.h"
|
||||||
#include "fsm_master.h"
|
#include "fsm_master.h"
|
||||||
|
#include "cdev.h"
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
@ -84,6 +85,8 @@ struct ec_master {
|
||||||
unsigned int index; /**< master index */
|
unsigned int index; /**< master index */
|
||||||
unsigned int reserved; /**< non-zero, if the master is reserved for RT */
|
unsigned int reserved; /**< non-zero, if the master is reserved for RT */
|
||||||
|
|
||||||
|
ec_cdev_t cdev; /**< Master character device. */
|
||||||
|
|
||||||
ec_device_t main_device; /**< EtherCAT device */
|
ec_device_t main_device; /**< EtherCAT device */
|
||||||
const uint8_t *main_mac; /**< MAC address of main device */
|
const uint8_t *main_mac; /**< MAC address of main device */
|
||||||
ec_device_t backup_device; /**< EtherCAT backup device */
|
ec_device_t backup_device; /**< EtherCAT backup device */
|
||||||
|
|
@ -166,7 +169,7 @@ struct ec_master {
|
||||||
|
|
||||||
// master creation/deletion
|
// master creation/deletion
|
||||||
int ec_master_init(ec_master_t *, struct kobject *, unsigned int,
|
int ec_master_init(ec_master_t *, struct kobject *, unsigned int,
|
||||||
const uint8_t *, const uint8_t *);
|
const uint8_t *, const uint8_t *, dev_t);
|
||||||
void ec_master_clear(ec_master_t *);
|
void ec_master_clear(ec_master_t *);
|
||||||
|
|
||||||
// mode transitions
|
// mode transitions
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
|
#include <linux/fs.h>
|
||||||
|
|
||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
#include "master.h"
|
#include "master.h"
|
||||||
|
|
@ -68,6 +69,8 @@ static struct semaphore master_sem; /**< Master semaphore. */
|
||||||
static unsigned int master_count; /**< Number of masters. */
|
static unsigned int master_count; /**< Number of masters. */
|
||||||
static unsigned int backup_count; /**< Number of backup devices. */
|
static unsigned int backup_count; /**< Number of backup devices. */
|
||||||
|
|
||||||
|
static dev_t device_number; /**< Device number for cdevs. */
|
||||||
|
|
||||||
static uint8_t macs[MAX_MASTERS][2][ETH_ALEN]; /**< MAC addresses. */
|
static uint8_t macs[MAX_MASTERS][2][ETH_ALEN]; /**< MAC addresses. */
|
||||||
|
|
||||||
char *ec_master_version_str = EC_MASTER_VERSION; /**< Version string. */
|
char *ec_master_version_str = EC_MASTER_VERSION; /**< Version string. */
|
||||||
|
|
@ -92,7 +95,7 @@ MODULE_PARM_DESC(backup_devices, "MAC addresses of backup devices");
|
||||||
|
|
||||||
/** Module initialization.
|
/** Module initialization.
|
||||||
*
|
*
|
||||||
* Initializes \a ec_master_count masters.
|
* Initializes \a master_count masters.
|
||||||
* \return 0 on success, else < 0
|
* \return 0 on success, else < 0
|
||||||
*/
|
*/
|
||||||
int __init ec_init_module(void)
|
int __init ec_init_module(void)
|
||||||
|
|
@ -119,6 +122,12 @@ int __init ec_init_module(void)
|
||||||
goto out_put;
|
goto out_put;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (alloc_chrdev_region(&device_number, 0, master_count, "EtherCAT")) {
|
||||||
|
EC_ERR("Failed to obtain device number(s)!\n");
|
||||||
|
ret = -EBUSY;
|
||||||
|
goto out_del;
|
||||||
|
}
|
||||||
|
|
||||||
// zero MAC addresses
|
// zero MAC addresses
|
||||||
memset(macs, 0x00, sizeof(uint8_t) * MAX_MASTERS * 2 * ETH_ALEN);
|
memset(macs, 0x00, sizeof(uint8_t) * MAX_MASTERS * 2 * ETH_ALEN);
|
||||||
|
|
||||||
|
|
@ -126,12 +135,12 @@ int __init ec_init_module(void)
|
||||||
for (i = 0; i < master_count; i++) {
|
for (i = 0; i < master_count; i++) {
|
||||||
if (ec_mac_parse(macs[i][0], main_devices[i], 0)) {
|
if (ec_mac_parse(macs[i][0], main_devices[i], 0)) {
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto out_del;
|
goto out_cdev;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i < backup_count && ec_mac_parse(macs[i][1], backup_devices[i], 1)) {
|
if (i < backup_count && ec_mac_parse(macs[i][1], backup_devices[i], 1)) {
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto out_del;
|
goto out_cdev;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -140,12 +149,13 @@ int __init ec_init_module(void)
|
||||||
GFP_KERNEL))) {
|
GFP_KERNEL))) {
|
||||||
EC_ERR("Failed to allocate memory for EtherCAT masters.\n");
|
EC_ERR("Failed to allocate memory for EtherCAT masters.\n");
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto out_del;
|
goto out_cdev;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < master_count; i++) {
|
for (i = 0; i < master_count; i++) {
|
||||||
if (ec_master_init(&masters[i], &kobj, i, macs[i][0], macs[i][1])) {
|
if (ec_master_init(&masters[i], &kobj, i, macs[i][0], macs[i][1],
|
||||||
|
device_number)) {
|
||||||
ret = -EIO;
|
ret = -EIO;
|
||||||
goto out_free_masters;
|
goto out_free_masters;
|
||||||
}
|
}
|
||||||
|
|
@ -158,6 +168,8 @@ int __init ec_init_module(void)
|
||||||
out_free_masters:
|
out_free_masters:
|
||||||
for (i--; i >= 0; i--) ec_master_clear(&masters[i]);
|
for (i--; i >= 0; i--) ec_master_clear(&masters[i]);
|
||||||
kfree(masters);
|
kfree(masters);
|
||||||
|
out_cdev:
|
||||||
|
unregister_chrdev_region(device_number, master_count);
|
||||||
out_del:
|
out_del:
|
||||||
kobject_del(&kobj);
|
kobject_del(&kobj);
|
||||||
out_put:
|
out_put:
|
||||||
|
|
@ -180,6 +192,8 @@ void __exit ec_cleanup_module(void)
|
||||||
}
|
}
|
||||||
if (master_count)
|
if (master_count)
|
||||||
kfree(masters);
|
kfree(masters);
|
||||||
|
|
||||||
|
unregister_chrdev_region(device_number, master_count);
|
||||||
|
|
||||||
kobject_del(&kobj);
|
kobject_del(&kobj);
|
||||||
kobject_put(&kobj);
|
kobject_put(&kobj);
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,7 @@
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
CDEV='EtherCAT'
|
||||||
MODPROBE=/sbin/modprobe
|
MODPROBE=/sbin/modprobe
|
||||||
RMMOD=/sbin/rmmod
|
RMMOD=/sbin/rmmod
|
||||||
MODINFO=/sbin/modinfo
|
MODINFO=/sbin/modinfo
|
||||||
|
|
@ -172,6 +173,7 @@ start)
|
||||||
|
|
||||||
MASTER_INDEX=$(expr ${MASTER_INDEX} + 1)
|
MASTER_INDEX=$(expr ${MASTER_INDEX} + 1)
|
||||||
done
|
done
|
||||||
|
MASTER_INDICES=`seq 0 $((${MASTER_INDEX} - 1))`
|
||||||
|
|
||||||
# load master module
|
# load master module
|
||||||
if ! ${MODPROBE} ${MODPROBE_FLAGS} ec_master \
|
if ! ${MODPROBE} ${MODPROBE_FLAGS} ec_master \
|
||||||
|
|
@ -179,6 +181,17 @@ start)
|
||||||
exit_fail
|
exit_fail
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# remove stale device nodes
|
||||||
|
rm -f /dev/${CDEV}*
|
||||||
|
|
||||||
|
# get dynamic major number
|
||||||
|
MAJOR=$(awk "\$2==\"EtherCAT\" {print \$1}" /proc/devices)
|
||||||
|
|
||||||
|
# create character devices
|
||||||
|
for i in ${MASTER_INDICES}; do
|
||||||
|
mknod /dev/${CDEV}${i} c ${MAJOR} ${i}
|
||||||
|
done
|
||||||
|
|
||||||
# check for modules to replace
|
# check for modules to replace
|
||||||
for MODULE in ${DEVICE_MODULES}; do
|
for MODULE in ${DEVICE_MODULES}; do
|
||||||
ECMODULE=ec_${MODULE}
|
ECMODULE=ec_${MODULE}
|
||||||
|
|
@ -213,6 +226,9 @@ stop)
|
||||||
fi;
|
fi;
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# remove device nodes
|
||||||
|
rm -f /dev/${CDEV}*
|
||||||
|
|
||||||
sleep 1
|
sleep 1
|
||||||
|
|
||||||
# reload previous modules
|
# reload previous modules
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# $Id$
|
||||||
|
#
|
||||||
|
# Copyright (C) 2006 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
|
||||||
|
# as published by the Free Software Foundation; either version 2 of the
|
||||||
|
# License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# 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 right to use EtherCAT Technology is granted and comes free of
|
||||||
|
# charge under condition of compatibility of product made by
|
||||||
|
# Licensee. People intending to distribute/sell products based on the
|
||||||
|
# code, have to sign an agreement to guarantee that products using
|
||||||
|
# software based on IgH EtherCAT master stay compatible with the actual
|
||||||
|
# EtherCAT specification (which are released themselves as an open
|
||||||
|
# standard) as the (only) precondition to have the right to use EtherCAT
|
||||||
|
# Technology, IP and trade marks.
|
||||||
|
#
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
bin_PROGRAMS = ethercat
|
||||||
|
|
||||||
|
ethercat_SOURCES = \
|
||||||
|
Master.cpp Master.h \
|
||||||
|
main.cpp
|
||||||
|
|
||||||
|
ethercat_CFLAGS = -I../master
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
|
@ -0,0 +1,140 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <sstream>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
#include "Master.h"
|
||||||
|
#include "../master/ioctl.h"
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
|
||||||
|
Master::Master()
|
||||||
|
{
|
||||||
|
index = 0;
|
||||||
|
fd = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
|
||||||
|
Master::~Master()
|
||||||
|
{
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
|
||||||
|
void Master::open(unsigned int index)
|
||||||
|
{
|
||||||
|
stringstream deviceName;
|
||||||
|
|
||||||
|
Master::index = index;
|
||||||
|
|
||||||
|
deviceName << "/dev/EtherCAT" << index;
|
||||||
|
|
||||||
|
if ((fd = ::open(deviceName.str().c_str(), O_RDONLY)) == -1) {
|
||||||
|
stringstream err;
|
||||||
|
err << "Failed to open master device " << deviceName.str() << ": "
|
||||||
|
<< strerror(errno);
|
||||||
|
throw MasterException(err.str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
|
||||||
|
void Master::close()
|
||||||
|
{
|
||||||
|
if (fd == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
::close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
|
||||||
|
unsigned int Master::slaveCount()
|
||||||
|
{
|
||||||
|
unsigned int numSlaves;
|
||||||
|
|
||||||
|
if (ioctl(fd, EC_IOCTL_SLAVE_COUNT, &numSlaves)) {
|
||||||
|
stringstream err;
|
||||||
|
err << "Failed to get number of slaves: " << strerror(errno);
|
||||||
|
throw MasterException(err.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
return numSlaves;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
|
||||||
|
void Master::listSlaves()
|
||||||
|
{
|
||||||
|
unsigned int numSlaves = slaveCount(), i;
|
||||||
|
struct ec_ioctl_slave_info *infos, *info;
|
||||||
|
uint16_t lastAlias, aliasIndex;
|
||||||
|
|
||||||
|
if (!numSlaves)
|
||||||
|
return;
|
||||||
|
|
||||||
|
infos = new struct ec_ioctl_slave_info[numSlaves];
|
||||||
|
|
||||||
|
if (ioctl(fd, EC_IOCTL_SLAVE_INFO, infos)) {
|
||||||
|
stringstream err;
|
||||||
|
err << "Failed to get slave information: " << strerror(errno);
|
||||||
|
throw MasterException(err.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
lastAlias = 0;
|
||||||
|
aliasIndex = 0;
|
||||||
|
for (i = 0; i < numSlaves; i++) {
|
||||||
|
info = &infos[i];
|
||||||
|
cout << setw(2) << info->ring_position << " ";
|
||||||
|
|
||||||
|
if (info->alias) {
|
||||||
|
lastAlias = info->alias;
|
||||||
|
aliasIndex = 0;
|
||||||
|
}
|
||||||
|
if (lastAlias) {
|
||||||
|
cout << setw(10) << "#" << lastAlias << ":" << aliasIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
cout << " " << slaveState(info->state) << " ";
|
||||||
|
|
||||||
|
if (strlen(info->description)) {
|
||||||
|
cout << info->description;
|
||||||
|
} else {
|
||||||
|
cout << "0x" << hex << setfill('0') << info->vendor_id
|
||||||
|
<< ":0x" << info->product_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
cout << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete [] infos;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
|
||||||
|
string Master::slaveState(uint8_t state) const
|
||||||
|
{
|
||||||
|
switch (state) {
|
||||||
|
case 1: return "INIT";
|
||||||
|
case 2: return "PREOP";
|
||||||
|
case 4: return "SAFEOP";
|
||||||
|
case 8: return "OP";
|
||||||
|
default: return "???";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __EC_MASTER_H__
|
||||||
|
#define __EC_MASTER_H__
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
|
||||||
|
class MasterException:
|
||||||
|
public runtime_error
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/** Constructor with std::string parameter. */
|
||||||
|
MasterException(
|
||||||
|
const string &s /**< Message. */
|
||||||
|
): runtime_error(s) {}
|
||||||
|
|
||||||
|
/** Constructor with const char pointer parameter. */
|
||||||
|
MasterException(
|
||||||
|
const char *s /**< Message. */
|
||||||
|
): runtime_error(s) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
|
||||||
|
class Master
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Master();
|
||||||
|
~Master();
|
||||||
|
|
||||||
|
void open(unsigned int);
|
||||||
|
void close();
|
||||||
|
|
||||||
|
unsigned int slaveCount();
|
||||||
|
void listSlaves();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
string slaveState(uint8_t) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
unsigned int index;
|
||||||
|
int fd;
|
||||||
|
};
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,117 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <getopt.h>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
#include "Master.h"
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
#define DEFAULT_MASTER 0
|
||||||
|
#define DEFAULT_COMMAND "slaves"
|
||||||
|
#define DEFAULT_SLAVESPEC ""
|
||||||
|
|
||||||
|
static unsigned int masterIndex = DEFAULT_MASTER;
|
||||||
|
static string slaveSpec = DEFAULT_SLAVESPEC;
|
||||||
|
static string command = DEFAULT_COMMAND;
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
void printUsage()
|
||||||
|
{
|
||||||
|
cerr
|
||||||
|
<< "Usage: ethercat <COMMAND> [OPTIONS]" << endl
|
||||||
|
<< "Commands:" << endl
|
||||||
|
<< " list (ls, slaves) List all slaves (former 'lsec')." << endl
|
||||||
|
<< "Global options:" << endl
|
||||||
|
<< " --master -m <master> Index of the master to use. Default: "
|
||||||
|
<< DEFAULT_MASTER << endl
|
||||||
|
<< " --slave -s <slave> Slave specification. Default: All "
|
||||||
|
"slaves." << endl
|
||||||
|
<< " --help -h Show this help." << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
void getOptions(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int c, argCount, optionIndex, number;
|
||||||
|
char *remainder;
|
||||||
|
|
||||||
|
static struct option longOptions[] = {
|
||||||
|
//name, has_arg, flag, val
|
||||||
|
{"master", required_argument, NULL, 'm'},
|
||||||
|
{"slave", required_argument, NULL, 's'},
|
||||||
|
{"help", no_argument, NULL, 'h'},
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
do {
|
||||||
|
c = getopt_long(argc, argv, "m:s:h", longOptions, &optionIndex);
|
||||||
|
|
||||||
|
switch (c) {
|
||||||
|
case 'm':
|
||||||
|
number = strtoul(optarg, &remainder, 0);
|
||||||
|
if (remainder == optarg || *remainder || number < 0) {
|
||||||
|
cerr << "Invalid master number " << optarg << "!" << endl;
|
||||||
|
printUsage();
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
masterIndex = number;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 's':
|
||||||
|
slaveSpec = optarg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'h':
|
||||||
|
case '?':
|
||||||
|
printUsage();
|
||||||
|
exit(0);
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (c != -1);
|
||||||
|
|
||||||
|
argCount = argc - optind;
|
||||||
|
|
||||||
|
if (!argCount) {
|
||||||
|
cerr << "Please specify a command!" << endl;
|
||||||
|
printUsage();
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
command = argv[optind];
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
Master master;
|
||||||
|
|
||||||
|
getOptions(argc, argv);
|
||||||
|
|
||||||
|
master.open(masterIndex);
|
||||||
|
|
||||||
|
if (command == "list" || command == "ls" || command == "slaves") {
|
||||||
|
master.listSlaves();
|
||||||
|
} else {
|
||||||
|
cerr << "Unknown command " << command << "!" << endl;
|
||||||
|
printUsage();
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
Loading…
Reference in New Issue