Multi-master support for command-line tool. The --master option supports
ranges like '1-3,6,7-9'. The ioctl() interface version is checked.
This commit is contained in:
parent
edf5fdf61f
commit
f41dadb84f
2
NEWS
2
NEWS
|
|
@ -65,6 +65,8 @@ Changes since 1.4.0:
|
|||
* Significantly improved EoE bandwidth by running EoE processing in a kthread.
|
||||
* Switched version control from Subversion to Mercurial.
|
||||
* Implemented CompleteAccess for SDO downloads.
|
||||
* ethercat tool is now able to handle multiple masters. The --masters option
|
||||
supports ranges like '0,3,8-10'.
|
||||
|
||||
Changes in 1.4.0:
|
||||
|
||||
|
|
|
|||
2
TODO
2
TODO
|
|
@ -38,7 +38,6 @@ Future issues:
|
|||
* Remove default buffer size in SDO upload.
|
||||
* Improve application-triggered SDO transfers by moving the state machine into
|
||||
the SDO handlers.
|
||||
* Check for ioctl() interface version.
|
||||
* Remove allow_scanning flag.
|
||||
* Override sync manager size?
|
||||
* Show Record / Array / List type of SDOs.
|
||||
|
|
@ -71,6 +70,7 @@ Future issues:
|
|||
- Data type abbreviations.
|
||||
- Add a -n (numeric) switch.
|
||||
- Check for unwanted options.
|
||||
- Implement ranges for slaves, domains, etc.
|
||||
* Simplify master fsm by introducing a common request state to handle external
|
||||
requests (replace write_sii, sdo_request, etc).
|
||||
|
||||
|
|
|
|||
26
lib/common.c
26
lib/common.c
|
|
@ -71,7 +71,8 @@ ec_master_t *ecrt_request_master(unsigned int master_index)
|
|||
ec_master_t *ecrt_open_master(unsigned int master_index)
|
||||
{
|
||||
char path[MAX_PATH_LEN];
|
||||
ec_master_t *master;
|
||||
ec_master_t *master = NULL;
|
||||
ec_ioctl_module_t module_data;
|
||||
|
||||
master = malloc(sizeof(ec_master_t));
|
||||
if (!master) {
|
||||
|
|
@ -87,11 +88,30 @@ ec_master_t *ecrt_open_master(unsigned int master_index)
|
|||
master->fd = open(path, O_RDWR);
|
||||
if (master->fd == -1) {
|
||||
fprintf(stderr, "Failed to open %s: %s\n", path, strerror(errno));
|
||||
free(master);
|
||||
return 0;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
if (ioctl(master->fd, EC_IOCTL_MODULE, &module_data) < 0) {
|
||||
fprintf(stderr, "Failed to get module information from %s: %s\n",
|
||||
path, strerror(errno));
|
||||
goto out_close;
|
||||
}
|
||||
|
||||
if (module_data.ioctl_version_magic != EC_IOCTL_VERSION_MAGIC) {
|
||||
fprintf(stderr, "ioctl() version magic is differing:"
|
||||
" %s: %u, libethercat: %u.\n",
|
||||
path, module_data.ioctl_version_magic,
|
||||
EC_IOCTL_VERSION_MAGIC);
|
||||
goto out_close;
|
||||
}
|
||||
|
||||
return master;
|
||||
|
||||
out_close:
|
||||
close(master->fd);
|
||||
out_free:
|
||||
free(master);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -157,6 +157,25 @@ void ec_cdev_strcpy(
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Get module information.
|
||||
*/
|
||||
int ec_cdev_ioctl_module(
|
||||
unsigned long arg /**< Userspace address to store the results. */
|
||||
)
|
||||
{
|
||||
ec_ioctl_module_t data;
|
||||
|
||||
data.ioctl_version_magic = EC_IOCTL_VERSION_MAGIC;
|
||||
data.master_count = ec_master_count();
|
||||
|
||||
if (copy_to_user((void __user *) arg, &data, sizeof(data)))
|
||||
return -EFAULT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Get master information.
|
||||
*/
|
||||
int ec_cdev_ioctl_master(
|
||||
|
|
@ -3281,6 +3300,8 @@ long eccdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|||
#endif
|
||||
|
||||
switch (cmd) {
|
||||
case EC_IOCTL_MODULE:
|
||||
return ec_cdev_ioctl_module(arg);
|
||||
case EC_IOCTL_MASTER:
|
||||
return ec_cdev_ioctl_master(master, arg);
|
||||
case EC_IOCTL_SLAVE:
|
||||
|
|
|
|||
|
|
@ -263,6 +263,7 @@ extern char *ec_master_version_str;
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
unsigned int ec_master_count(void);
|
||||
void ec_print_data(const uint8_t *, size_t);
|
||||
void ec_print_data_diff(const uint8_t *, const uint8_t *, size_t);
|
||||
size_t ec_state_string(uint8_t, char *, uint8_t);
|
||||
|
|
|
|||
148
master/ioctl.h
148
master/ioctl.h
|
|
@ -52,78 +52,85 @@
|
|||
#define EC_IOW(nr, type) _IOW(EC_IOCTL_TYPE, nr, type)
|
||||
#define EC_IOWR(nr, type) _IOWR(EC_IOCTL_TYPE, nr, type)
|
||||
|
||||
/** EtherCAT master ioctl() version magic.
|
||||
*
|
||||
* Increment this when changing the ioctl interface!
|
||||
*/
|
||||
#define EC_IOCTL_VERSION_MAGIC 1
|
||||
|
||||
// Command-line tool
|
||||
#define EC_IOCTL_MASTER EC_IOR(0x00, ec_ioctl_master_t)
|
||||
#define EC_IOCTL_SLAVE EC_IOWR(0x01, ec_ioctl_slave_t)
|
||||
#define EC_IOCTL_SLAVE_SYNC EC_IOWR(0x02, ec_ioctl_slave_sync_t)
|
||||
#define EC_IOCTL_SLAVE_SYNC_PDO EC_IOWR(0x03, ec_ioctl_slave_sync_pdo_t)
|
||||
#define EC_IOCTL_SLAVE_SYNC_PDO_ENTRY EC_IOWR(0x04, ec_ioctl_slave_sync_pdo_entry_t)
|
||||
#define EC_IOCTL_DOMAIN EC_IOWR(0x05, ec_ioctl_domain_t)
|
||||
#define EC_IOCTL_DOMAIN_FMMU EC_IOWR(0x06, ec_ioctl_domain_fmmu_t)
|
||||
#define EC_IOCTL_DOMAIN_DATA EC_IOWR(0x07, ec_ioctl_domain_data_t)
|
||||
#define EC_IOCTL_MASTER_DEBUG EC_IO(0x08)
|
||||
#define EC_IOCTL_SLAVE_STATE EC_IOW(0x09, ec_ioctl_slave_state_t)
|
||||
#define EC_IOCTL_SLAVE_SDO EC_IOWR(0x0a, ec_ioctl_slave_sdo_t)
|
||||
#define EC_IOCTL_SLAVE_SDO_ENTRY EC_IOWR(0x0b, ec_ioctl_slave_sdo_entry_t)
|
||||
#define EC_IOCTL_SLAVE_SDO_UPLOAD EC_IOWR(0x0c, ec_ioctl_slave_sdo_upload_t)
|
||||
#define EC_IOCTL_SLAVE_SDO_DOWNLOAD EC_IOWR(0x0d, ec_ioctl_slave_sdo_download_t)
|
||||
#define EC_IOCTL_SLAVE_SII_READ EC_IOWR(0x0e, ec_ioctl_slave_sii_t)
|
||||
#define EC_IOCTL_SLAVE_SII_WRITE EC_IOW(0x0f, ec_ioctl_slave_sii_t)
|
||||
#define EC_IOCTL_SLAVE_REG_READ EC_IOWR(0x10, ec_ioctl_slave_reg_t)
|
||||
#define EC_IOCTL_SLAVE_REG_WRITE EC_IOW(0x11, ec_ioctl_slave_reg_t)
|
||||
#define EC_IOCTL_SLAVE_FOE_READ EC_IOWR(0x12, ec_ioctl_slave_foe_t)
|
||||
#define EC_IOCTL_SLAVE_FOE_WRITE EC_IOW(0x13, ec_ioctl_slave_foe_t)
|
||||
#define EC_IOCTL_CONFIG EC_IOWR(0x14, ec_ioctl_config_t)
|
||||
#define EC_IOCTL_CONFIG_PDO EC_IOWR(0x15, ec_ioctl_config_pdo_t)
|
||||
#define EC_IOCTL_CONFIG_PDO_ENTRY EC_IOWR(0x16, ec_ioctl_config_pdo_entry_t)
|
||||
#define EC_IOCTL_CONFIG_SDO EC_IOWR(0x17, ec_ioctl_config_sdo_t)
|
||||
#define EC_IOCTL_MODULE EC_IOR(0x00, ec_ioctl_module_t)
|
||||
#define EC_IOCTL_MASTER EC_IOR(0x01, ec_ioctl_master_t)
|
||||
#define EC_IOCTL_SLAVE EC_IOWR(0x02, ec_ioctl_slave_t)
|
||||
#define EC_IOCTL_SLAVE_SYNC EC_IOWR(0x03, ec_ioctl_slave_sync_t)
|
||||
#define EC_IOCTL_SLAVE_SYNC_PDO EC_IOWR(0x04, ec_ioctl_slave_sync_pdo_t)
|
||||
#define EC_IOCTL_SLAVE_SYNC_PDO_ENTRY EC_IOWR(0x05, ec_ioctl_slave_sync_pdo_entry_t)
|
||||
#define EC_IOCTL_DOMAIN EC_IOWR(0x06, ec_ioctl_domain_t)
|
||||
#define EC_IOCTL_DOMAIN_FMMU EC_IOWR(0x07, ec_ioctl_domain_fmmu_t)
|
||||
#define EC_IOCTL_DOMAIN_DATA EC_IOWR(0x08, ec_ioctl_domain_data_t)
|
||||
#define EC_IOCTL_MASTER_DEBUG EC_IO(0x09)
|
||||
#define EC_IOCTL_SLAVE_STATE EC_IOW(0x0a, ec_ioctl_slave_state_t)
|
||||
#define EC_IOCTL_SLAVE_SDO EC_IOWR(0x0b, ec_ioctl_slave_sdo_t)
|
||||
#define EC_IOCTL_SLAVE_SDO_ENTRY EC_IOWR(0x0c, ec_ioctl_slave_sdo_entry_t)
|
||||
#define EC_IOCTL_SLAVE_SDO_UPLOAD EC_IOWR(0x0d, ec_ioctl_slave_sdo_upload_t)
|
||||
#define EC_IOCTL_SLAVE_SDO_DOWNLOAD EC_IOWR(0x0e, ec_ioctl_slave_sdo_download_t)
|
||||
#define EC_IOCTL_SLAVE_SII_READ EC_IOWR(0x0f, ec_ioctl_slave_sii_t)
|
||||
#define EC_IOCTL_SLAVE_SII_WRITE EC_IOW(0x10, ec_ioctl_slave_sii_t)
|
||||
#define EC_IOCTL_SLAVE_REG_READ EC_IOWR(0x11, ec_ioctl_slave_reg_t)
|
||||
#define EC_IOCTL_SLAVE_REG_WRITE EC_IOW(0x12, ec_ioctl_slave_reg_t)
|
||||
#define EC_IOCTL_SLAVE_FOE_READ EC_IOWR(0x13, ec_ioctl_slave_foe_t)
|
||||
#define EC_IOCTL_SLAVE_FOE_WRITE EC_IOW(0x14, ec_ioctl_slave_foe_t)
|
||||
#define EC_IOCTL_CONFIG EC_IOWR(0x15, ec_ioctl_config_t)
|
||||
#define EC_IOCTL_CONFIG_PDO EC_IOWR(0x16, ec_ioctl_config_pdo_t)
|
||||
#define EC_IOCTL_CONFIG_PDO_ENTRY EC_IOWR(0x17, ec_ioctl_config_pdo_entry_t)
|
||||
#define EC_IOCTL_CONFIG_SDO EC_IOWR(0x18, ec_ioctl_config_sdo_t)
|
||||
#ifdef EC_EOE
|
||||
#define EC_IOCTL_EOE_HANDLER EC_IOWR(0x18, ec_ioctl_eoe_handler_t)
|
||||
#define EC_IOCTL_EOE_HANDLER EC_IOWR(0x19, ec_ioctl_eoe_handler_t)
|
||||
#endif
|
||||
|
||||
// Application interface
|
||||
#define EC_IOCTL_REQUEST EC_IO(0x19)
|
||||
#define EC_IOCTL_CREATE_DOMAIN EC_IO(0x1a)
|
||||
#define EC_IOCTL_CREATE_SLAVE_CONFIG EC_IOWR(0x1b, ec_ioctl_config_t)
|
||||
#define EC_IOCTL_ACTIVATE EC_IOR(0x1c, size_t)
|
||||
#define EC_IOCTL_DEACTIVATE EC_IO(0x1d)
|
||||
#define EC_IOCTL_SEND EC_IO(0x1e)
|
||||
#define EC_IOCTL_RECEIVE EC_IO(0x1f)
|
||||
#define EC_IOCTL_MASTER_STATE EC_IOR(0x20, ec_master_state_t)
|
||||
#define EC_IOCTL_APP_TIME EC_IOW(0x21, ec_ioctl_app_time_t)
|
||||
#define EC_IOCTL_SYNC_REF EC_IO(0x22)
|
||||
#define EC_IOCTL_SYNC_SLAVES EC_IO(0x23)
|
||||
#define EC_IOCTL_SYNC_MON_QUEUE EC_IO(0x24)
|
||||
#define EC_IOCTL_SYNC_MON_PROCESS EC_IOR(0x25, uint32_t)
|
||||
#define EC_IOCTL_SC_SYNC EC_IOW(0x26, ec_ioctl_config_t)
|
||||
#define EC_IOCTL_SC_WATCHDOG EC_IOW(0x27, ec_ioctl_config_t)
|
||||
#define EC_IOCTL_SC_ADD_PDO EC_IOW(0x28, ec_ioctl_config_pdo_t)
|
||||
#define EC_IOCTL_SC_CLEAR_PDOS EC_IOW(0x29, ec_ioctl_config_pdo_t)
|
||||
#define EC_IOCTL_SC_ADD_ENTRY EC_IOW(0x2a, ec_ioctl_add_pdo_entry_t)
|
||||
#define EC_IOCTL_SC_CLEAR_ENTRIES EC_IOW(0x2b, ec_ioctl_config_pdo_t)
|
||||
#define EC_IOCTL_SC_REG_PDO_ENTRY EC_IOWR(0x2c, ec_ioctl_reg_pdo_entry_t)
|
||||
#define EC_IOCTL_SC_DC EC_IOW(0x2d, ec_ioctl_config_t)
|
||||
#define EC_IOCTL_SC_SDO EC_IOW(0x2e, ec_ioctl_sc_sdo_t)
|
||||
#define EC_IOCTL_SC_SDO_REQUEST EC_IOWR(0x2f, ec_ioctl_sdo_request_t)
|
||||
#define EC_IOCTL_SC_VOE EC_IOWR(0x20, ec_ioctl_voe_t)
|
||||
#define EC_IOCTL_SC_STATE EC_IOWR(0x31, ec_ioctl_sc_state_t)
|
||||
#define EC_IOCTL_DOMAIN_OFFSET EC_IO(0x32)
|
||||
#define EC_IOCTL_DOMAIN_PROCESS EC_IO(0x33)
|
||||
#define EC_IOCTL_DOMAIN_QUEUE EC_IO(0x34)
|
||||
#define EC_IOCTL_DOMAIN_STATE EC_IOWR(0x35, ec_ioctl_domain_state_t)
|
||||
#define EC_IOCTL_SDO_REQUEST_TIMEOUT EC_IOWR(0x36, ec_ioctl_sdo_request_t)
|
||||
#define EC_IOCTL_SDO_REQUEST_STATE EC_IOWR(0x37, ec_ioctl_sdo_request_t)
|
||||
#define EC_IOCTL_SDO_REQUEST_READ EC_IOWR(0x38, ec_ioctl_sdo_request_t)
|
||||
#define EC_IOCTL_SDO_REQUEST_WRITE EC_IOWR(0x39, ec_ioctl_sdo_request_t)
|
||||
#define EC_IOCTL_SDO_REQUEST_DATA EC_IOWR(0x3a, ec_ioctl_sdo_request_t)
|
||||
#define EC_IOCTL_VOE_SEND_HEADER EC_IOW(0x3b, ec_ioctl_voe_t)
|
||||
#define EC_IOCTL_VOE_REC_HEADER EC_IOWR(0x3c, ec_ioctl_voe_t)
|
||||
#define EC_IOCTL_VOE_READ EC_IOW(0x3d, ec_ioctl_voe_t)
|
||||
#define EC_IOCTL_VOE_READ_NOSYNC EC_IOW(0x3e, ec_ioctl_voe_t)
|
||||
#define EC_IOCTL_VOE_WRITE EC_IOWR(0x3f, ec_ioctl_voe_t)
|
||||
#define EC_IOCTL_VOE_EXEC EC_IOWR(0x40, ec_ioctl_voe_t)
|
||||
#define EC_IOCTL_VOE_DATA EC_IOWR(0x41, ec_ioctl_voe_t)
|
||||
#define EC_IOCTL_SET_SEND_INTERVAL EC_IOW(0x42, size_t)
|
||||
#define EC_IOCTL_REQUEST EC_IO(0x1a)
|
||||
#define EC_IOCTL_CREATE_DOMAIN EC_IO(0x1b)
|
||||
#define EC_IOCTL_CREATE_SLAVE_CONFIG EC_IOWR(0x1c, ec_ioctl_config_t)
|
||||
#define EC_IOCTL_ACTIVATE EC_IOR(0x1d, size_t)
|
||||
#define EC_IOCTL_DEACTIVATE EC_IO(0x1e)
|
||||
#define EC_IOCTL_SEND EC_IO(0x1f)
|
||||
#define EC_IOCTL_RECEIVE EC_IO(0x20)
|
||||
#define EC_IOCTL_MASTER_STATE EC_IOR(0x21, ec_master_state_t)
|
||||
#define EC_IOCTL_APP_TIME EC_IOW(0x22, ec_ioctl_app_time_t)
|
||||
#define EC_IOCTL_SYNC_REF EC_IO(0x23)
|
||||
#define EC_IOCTL_SYNC_SLAVES EC_IO(0x24)
|
||||
#define EC_IOCTL_SYNC_MON_QUEUE EC_IO(0x25)
|
||||
#define EC_IOCTL_SYNC_MON_PROCESS EC_IOR(0x26, uint32_t)
|
||||
#define EC_IOCTL_SC_SYNC EC_IOW(0x27, ec_ioctl_config_t)
|
||||
#define EC_IOCTL_SC_WATCHDOG EC_IOW(0x28, ec_ioctl_config_t)
|
||||
#define EC_IOCTL_SC_ADD_PDO EC_IOW(0x29, ec_ioctl_config_pdo_t)
|
||||
#define EC_IOCTL_SC_CLEAR_PDOS EC_IOW(0x2a, ec_ioctl_config_pdo_t)
|
||||
#define EC_IOCTL_SC_ADD_ENTRY EC_IOW(0x2b, ec_ioctl_add_pdo_entry_t)
|
||||
#define EC_IOCTL_SC_CLEAR_ENTRIES EC_IOW(0x2c, ec_ioctl_config_pdo_t)
|
||||
#define EC_IOCTL_SC_REG_PDO_ENTRY EC_IOWR(0x2d, ec_ioctl_reg_pdo_entry_t)
|
||||
#define EC_IOCTL_SC_DC EC_IOW(0x2e, ec_ioctl_config_t)
|
||||
#define EC_IOCTL_SC_SDO EC_IOW(0x2f, ec_ioctl_sc_sdo_t)
|
||||
#define EC_IOCTL_SC_SDO_REQUEST EC_IOWR(0x20, ec_ioctl_sdo_request_t)
|
||||
#define EC_IOCTL_SC_VOE EC_IOWR(0x31, ec_ioctl_voe_t)
|
||||
#define EC_IOCTL_SC_STATE EC_IOWR(0x32, ec_ioctl_sc_state_t)
|
||||
#define EC_IOCTL_DOMAIN_OFFSET EC_IO(0x33)
|
||||
#define EC_IOCTL_DOMAIN_PROCESS EC_IO(0x34)
|
||||
#define EC_IOCTL_DOMAIN_QUEUE EC_IO(0x35)
|
||||
#define EC_IOCTL_DOMAIN_STATE EC_IOWR(0x36, ec_ioctl_domain_state_t)
|
||||
#define EC_IOCTL_SDO_REQUEST_TIMEOUT EC_IOWR(0x37, ec_ioctl_sdo_request_t)
|
||||
#define EC_IOCTL_SDO_REQUEST_STATE EC_IOWR(0x38, ec_ioctl_sdo_request_t)
|
||||
#define EC_IOCTL_SDO_REQUEST_READ EC_IOWR(0x39, ec_ioctl_sdo_request_t)
|
||||
#define EC_IOCTL_SDO_REQUEST_WRITE EC_IOWR(0x3a, ec_ioctl_sdo_request_t)
|
||||
#define EC_IOCTL_SDO_REQUEST_DATA EC_IOWR(0x3b, ec_ioctl_sdo_request_t)
|
||||
#define EC_IOCTL_VOE_SEND_HEADER EC_IOW(0x3c, ec_ioctl_voe_t)
|
||||
#define EC_IOCTL_VOE_REC_HEADER EC_IOWR(0x3d, ec_ioctl_voe_t)
|
||||
#define EC_IOCTL_VOE_READ EC_IOW(0x3e, ec_ioctl_voe_t)
|
||||
#define EC_IOCTL_VOE_READ_NOSYNC EC_IOW(0x3f, ec_ioctl_voe_t)
|
||||
#define EC_IOCTL_VOE_WRITE EC_IOWR(0x40, ec_ioctl_voe_t)
|
||||
#define EC_IOCTL_VOE_EXEC EC_IOWR(0x41, ec_ioctl_voe_t)
|
||||
#define EC_IOCTL_VOE_DATA EC_IOWR(0x42, ec_ioctl_voe_t)
|
||||
#define EC_IOCTL_SET_SEND_INTERVAL EC_IOW(0x43, size_t)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
@ -131,6 +138,13 @@
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
uint32_t ioctl_version_magic;
|
||||
uint32_t master_count;
|
||||
} ec_ioctl_module_t;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
uint32_t slave_count;
|
||||
uint32_t config_count;
|
||||
|
|
|
|||
|
|
@ -195,6 +195,15 @@ void __exit ec_cleanup_module(void)
|
|||
EC_INFO("Master module cleaned up.\n");
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Get the number of masters.
|
||||
*/
|
||||
unsigned int ec_master_count(void)
|
||||
{
|
||||
return master_count;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* MAC address functions
|
||||
****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
****************************************************************************/
|
||||
|
||||
#include "Command.h"
|
||||
#include "MasterDevice.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
@ -46,6 +47,13 @@ Command::~Command()
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
void Command::setMasterIndices(const MasterIndexList &indices)
|
||||
{
|
||||
masterIndices = indices;
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void Command::setVerbosity(Verbosity v)
|
||||
{
|
||||
verbosity = v;
|
||||
|
|
|
|||
|
|
@ -33,9 +33,12 @@
|
|||
#include <stdexcept>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <sstream>
|
||||
using namespace std;
|
||||
|
||||
#include "MasterDevice.h"
|
||||
#include "../master/ioctl.h"
|
||||
|
||||
class MasterDevice;
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
|
|
@ -76,6 +79,9 @@ class Command
|
|||
const string &getName() const;
|
||||
const string &getBriefDescription() const;
|
||||
|
||||
typedef list<unsigned int> MasterIndexList;
|
||||
void setMasterIndices(const MasterIndexList &);
|
||||
const MasterIndexList &getMasterIndices() const;
|
||||
enum Verbosity {
|
||||
Quiet,
|
||||
Normal,
|
||||
|
|
@ -102,7 +108,7 @@ class Command
|
|||
virtual string helpString() const = 0;
|
||||
|
||||
typedef vector<string> StringVector;
|
||||
virtual void execute(MasterDevice &, const StringVector &) = 0;
|
||||
virtual void execute(const StringVector &) = 0;
|
||||
|
||||
static string numericInfo();
|
||||
|
||||
|
|
@ -125,6 +131,7 @@ class Command
|
|||
private:
|
||||
string name;
|
||||
string briefDesc;
|
||||
MasterIndexList masterIndices;
|
||||
Verbosity verbosity;
|
||||
int alias;
|
||||
int position;
|
||||
|
|
@ -152,6 +159,13 @@ inline const string &Command::getBriefDescription() const
|
|||
|
||||
/****************************************************************************/
|
||||
|
||||
inline const Command::MasterIndexList &Command::getMasterIndices() const
|
||||
{
|
||||
return masterIndices;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
inline Command::Verbosity Command::getVerbosity() const
|
||||
{
|
||||
return verbosity;
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ using namespace std;
|
|||
|
||||
#include "CommandAlias.h"
|
||||
#include "sii_crc.h"
|
||||
#include "MasterDevice.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
@ -75,7 +76,7 @@ string CommandAlias::helpString() const
|
|||
|
||||
/** Writes the Secondary slave address (alias) to the slave's SII.
|
||||
*/
|
||||
void CommandAlias::execute(MasterDevice &m, const StringVector &args)
|
||||
void CommandAlias::execute(const StringVector &args)
|
||||
{
|
||||
uint16_t alias;
|
||||
stringstream err, strAlias;
|
||||
|
|
@ -98,6 +99,11 @@ void CommandAlias::execute(MasterDevice &m, const StringVector &args)
|
|||
}
|
||||
alias = number;
|
||||
|
||||
if (getMasterIndices().size() != 1) {
|
||||
err << getName() << " requires to select a single master!";
|
||||
throwInvalidUsageException(err);
|
||||
}
|
||||
MasterDevice m(getMasterIndices().front());
|
||||
m.open(MasterDevice::ReadWrite);
|
||||
slaves = selectedSlaves(m);
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class CommandAlias:
|
|||
CommandAlias();
|
||||
|
||||
string helpString() const;
|
||||
void execute(MasterDevice &, const StringVector &);
|
||||
void execute(const StringVector &);
|
||||
|
||||
protected:
|
||||
void writeSlaveAlias(MasterDevice &, const ec_ioctl_slave_t &,
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
using namespace std;
|
||||
|
||||
#include "CommandCStruct.h"
|
||||
#include "MasterDevice.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
@ -67,7 +68,7 @@ string CommandCStruct::helpString() const
|
|||
|
||||
/****************************************************************************/
|
||||
|
||||
void CommandCStruct::execute(MasterDevice &m, const StringVector &args)
|
||||
void CommandCStruct::execute(const StringVector &args)
|
||||
{
|
||||
SlaveList slaves;
|
||||
SlaveList::const_iterator si;
|
||||
|
|
@ -78,11 +79,16 @@ void CommandCStruct::execute(MasterDevice &m, const StringVector &args)
|
|||
throwInvalidUsageException(err);
|
||||
}
|
||||
|
||||
m.open(MasterDevice::Read);
|
||||
slaves = selectedSlaves(m);
|
||||
MasterIndexList::const_iterator mi;
|
||||
for (mi = getMasterIndices().begin();
|
||||
mi != getMasterIndices().end(); mi++) {
|
||||
MasterDevice m(*mi);
|
||||
m.open(MasterDevice::Read);
|
||||
slaves = selectedSlaves(m);
|
||||
|
||||
for (si = slaves.begin(); si != slaves.end(); si++) {
|
||||
generateSlaveCStruct(m, *si);
|
||||
for (si = slaves.begin(); si != slaves.end(); si++) {
|
||||
generateSlaveCStruct(m, *si);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class CommandCStruct:
|
|||
CommandCStruct();
|
||||
|
||||
string helpString() const;
|
||||
void execute(MasterDevice &, const StringVector &);
|
||||
void execute(const StringVector &);
|
||||
|
||||
protected:
|
||||
void generateSlaveCStruct(MasterDevice &, const ec_ioctl_slave_t &);
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
using namespace std;
|
||||
|
||||
#include "CommandConfig.h"
|
||||
#include "MasterDevice.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
@ -101,9 +102,10 @@ string CommandConfig::helpString() const
|
|||
|
||||
/** Lists the bus configuration.
|
||||
*/
|
||||
void CommandConfig::execute(MasterDevice &m, const StringVector &args)
|
||||
void CommandConfig::execute(const StringVector &args)
|
||||
{
|
||||
ConfigList configs;
|
||||
bool doIndent;
|
||||
|
||||
if (args.size()) {
|
||||
stringstream err;
|
||||
|
|
@ -111,13 +113,23 @@ void CommandConfig::execute(MasterDevice &m, const StringVector &args)
|
|||
throwInvalidUsageException(err);
|
||||
}
|
||||
|
||||
m.open(MasterDevice::Read);
|
||||
configs = selectedConfigs(m);
|
||||
doIndent = getMasterIndices().size() > 1;
|
||||
MasterIndexList::const_iterator mi;
|
||||
for (mi = getMasterIndices().begin();
|
||||
mi != getMasterIndices().end(); mi++) {
|
||||
MasterDevice m(*mi);
|
||||
m.open(MasterDevice::Read);
|
||||
configs = selectedConfigs(m);
|
||||
|
||||
if (getVerbosity() == Verbose) {
|
||||
showDetailedConfigs(m, configs);
|
||||
} else {
|
||||
listConfigs(m, configs);
|
||||
if (doIndent) {
|
||||
cout << "Master" << dec << *mi << endl;
|
||||
}
|
||||
|
||||
if (getVerbosity() == Verbose) {
|
||||
showDetailedConfigs(m, configs, doIndent);
|
||||
} else {
|
||||
listConfigs(m, configs, doIndent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -127,7 +139,8 @@ void CommandConfig::execute(MasterDevice &m, const StringVector &args)
|
|||
*/
|
||||
void CommandConfig::showDetailedConfigs(
|
||||
MasterDevice &m,
|
||||
const ConfigList &configList
|
||||
const ConfigList &configList,
|
||||
bool doIndent
|
||||
)
|
||||
{
|
||||
ConfigList::const_iterator configIter;
|
||||
|
|
@ -136,19 +149,21 @@ void CommandConfig::showDetailedConfigs(
|
|||
ec_ioctl_config_pdo_t pdo;
|
||||
ec_ioctl_config_pdo_entry_t entry;
|
||||
ec_ioctl_config_sdo_t sdo;
|
||||
string indent(doIndent ? " " : "");
|
||||
|
||||
for (configIter = configList.begin();
|
||||
configIter != configList.end();
|
||||
configIter++) {
|
||||
|
||||
cout << "Alias: "
|
||||
<< dec << configIter->alias << endl
|
||||
<< "Position: " << configIter->position << endl
|
||||
cout << indent
|
||||
<< "Alias: "
|
||||
<< dec << configIter->alias << endl << indent
|
||||
<< "Position: " << configIter->position << endl << indent
|
||||
<< "Vendor Id: 0x"
|
||||
<< hex << setfill('0')
|
||||
<< setw(8) << configIter->vendor_id << endl
|
||||
<< setw(8) << configIter->vendor_id << endl << indent
|
||||
<< "Product code: 0x"
|
||||
<< setw(8) << configIter->product_code << endl
|
||||
<< setw(8) << configIter->product_code << endl << indent
|
||||
<< "Attached slave: ";
|
||||
|
||||
if (configIter->slave_position != -1) {
|
||||
|
|
@ -159,13 +174,13 @@ void CommandConfig::showDetailedConfigs(
|
|||
cout << "none" << endl;
|
||||
}
|
||||
|
||||
cout << "Watchdog divider: ";
|
||||
cout << indent << "Watchdog divider: ";
|
||||
if (configIter->watchdog_divider) {
|
||||
cout << dec << configIter->watchdog_divider;
|
||||
} else {
|
||||
cout << "(Default)";
|
||||
}
|
||||
cout << endl
|
||||
cout << endl << indent
|
||||
<< "Watchdog intervals: ";
|
||||
if (configIter->watchdog_intervals) {
|
||||
cout << dec << configIter->watchdog_intervals;
|
||||
|
|
@ -176,7 +191,7 @@ void CommandConfig::showDetailedConfigs(
|
|||
|
||||
for (j = 0; j < EC_MAX_SYNC_MANAGERS; j++) {
|
||||
if (configIter->syncs[j].pdo_count) {
|
||||
cout << "SM" << dec << j << ", Dir: "
|
||||
cout << indent << "SM" << dec << j << ", Dir: "
|
||||
<< (configIter->syncs[j].dir == EC_DIR_INPUT
|
||||
? "Input" : "Output") << ", Watchdog: ";
|
||||
switch (configIter->syncs[j].watchdog_mode) {
|
||||
|
|
@ -190,14 +205,15 @@ void CommandConfig::showDetailedConfigs(
|
|||
for (k = 0; k < configIter->syncs[j].pdo_count; k++) {
|
||||
m.getConfigPdo(&pdo, configIter->config_index, j, k);
|
||||
|
||||
cout << " PDO 0x" << hex << setfill('0')
|
||||
cout << indent << " PDO 0x" << hex << setfill('0')
|
||||
<< setw(4) << pdo.index << endl;
|
||||
|
||||
for (l = 0; l < pdo.entry_count; l++) {
|
||||
m.getConfigPdoEntry(&entry,
|
||||
configIter->config_index, j, k, l);
|
||||
|
||||
cout << " PDO entry 0x" << hex << setfill('0')
|
||||
cout << indent << " PDO entry 0x"
|
||||
<< hex << setfill('0')
|
||||
<< setw(4) << entry.index << ":"
|
||||
<< setw(2) << (unsigned int) entry.subindex
|
||||
<< ", " << dec << setfill(' ')
|
||||
|
|
@ -208,23 +224,23 @@ void CommandConfig::showDetailedConfigs(
|
|||
}
|
||||
}
|
||||
|
||||
cout << "SDO configuration:" << endl;
|
||||
cout << indent << "SDO configuration:" << endl;
|
||||
if (configIter->sdo_count) {
|
||||
for (j = 0; j < configIter->sdo_count; j++) {
|
||||
m.getConfigSdo(&sdo, configIter->config_index, j);
|
||||
|
||||
cout << " 0x"
|
||||
cout << indent << " 0x"
|
||||
<< hex << setfill('0')
|
||||
<< setw(4) << sdo.index << ":"
|
||||
<< setw(2) << (unsigned int) sdo.subindex
|
||||
<< ", " << dec << sdo.size << " byte" << endl;
|
||||
|
||||
cout << " " << hex;
|
||||
cout << indent << " " << hex;
|
||||
for (i = 0; i < min((uint32_t) sdo.size,
|
||||
(uint32_t) EC_MAX_SDO_DATA_SIZE); i++) {
|
||||
cout << setw(2) << (unsigned int) sdo.data[i];
|
||||
if ((i + 1) % 16 == 0 && i < sdo.size - 1) {
|
||||
cout << endl << " ";
|
||||
cout << endl << indent << " ";
|
||||
} else {
|
||||
cout << " ";
|
||||
}
|
||||
|
|
@ -232,23 +248,23 @@ void CommandConfig::showDetailedConfigs(
|
|||
|
||||
cout << endl;
|
||||
if (sdo.size > EC_MAX_SDO_DATA_SIZE) {
|
||||
cout << " ..." << endl;
|
||||
cout << indent << " ..." << endl;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cout << " None." << endl;
|
||||
cout << indent << " None." << endl;
|
||||
}
|
||||
|
||||
if (configIter->dc_assign_activate) {
|
||||
int i;
|
||||
|
||||
cout << "DC configuration:" << endl
|
||||
<< " AssignActivate: 0x" << hex << setfill('0')
|
||||
cout << indent << "DC configuration:" << endl
|
||||
<< indent << " AssignActivate: 0x" << hex << setfill('0')
|
||||
<< setw(4) << configIter->dc_assign_activate << endl;
|
||||
|
||||
cout << " Cycle [ns] Shift [ns]" << endl;
|
||||
cout << indent << " Cycle [ns] Shift [ns]" << endl;
|
||||
for (i = 0; i < EC_SYNC_SIGNAL_COUNT; i++) {
|
||||
cout << " SYNC" << dec << i << " "
|
||||
cout << indent << " SYNC" << dec << i << " "
|
||||
<< setfill(' ') << right
|
||||
<< setw(11) << configIter->dc_sync[i].cycle_time
|
||||
<< " "
|
||||
|
|
@ -266,7 +282,8 @@ void CommandConfig::showDetailedConfigs(
|
|||
*/
|
||||
void CommandConfig::listConfigs(
|
||||
MasterDevice &m,
|
||||
const ConfigList &configList
|
||||
const ConfigList &configList,
|
||||
bool doIndent
|
||||
)
|
||||
{
|
||||
ConfigList::const_iterator configIter;
|
||||
|
|
@ -278,6 +295,7 @@ void CommandConfig::listConfigs(
|
|||
unsigned int maxAliasWidth = 0, maxPosWidth = 0,
|
||||
maxSlavePosWidth = 0, maxStateWidth = 0;
|
||||
ec_ioctl_slave_t slave;
|
||||
string indent(doIndent ? " " : "");
|
||||
|
||||
for (configIter = configList.begin();
|
||||
configIter != configList.end();
|
||||
|
|
@ -337,7 +355,7 @@ void CommandConfig::listConfigs(
|
|||
}
|
||||
|
||||
for (iter = list.begin(); iter != list.end(); iter++) {
|
||||
cout << setfill(' ') << right
|
||||
cout << indent << setfill(' ') << right
|
||||
<< setw(maxAliasWidth) << iter->alias
|
||||
<< ":" << left
|
||||
<< setw(maxPosWidth) << iter->pos
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ class CommandConfig:
|
|||
CommandConfig();
|
||||
|
||||
string helpString() const;
|
||||
void execute(MasterDevice &, const StringVector &);
|
||||
void execute(const StringVector &);
|
||||
|
||||
protected:
|
||||
struct Info {
|
||||
|
|
@ -55,8 +55,8 @@ class CommandConfig:
|
|||
string state;
|
||||
};
|
||||
|
||||
void showDetailedConfigs(MasterDevice &, const ConfigList &);
|
||||
void listConfigs(MasterDevice &m, const ConfigList &);
|
||||
void showDetailedConfigs(MasterDevice &, const ConfigList &, bool);
|
||||
void listConfigs(MasterDevice &m, const ConfigList &, bool);
|
||||
};
|
||||
|
||||
/****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
using namespace std;
|
||||
|
||||
#include "CommandData.h"
|
||||
#include "MasterDevice.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
@ -63,7 +64,7 @@ string CommandData::helpString() const
|
|||
|
||||
/****************************************************************************/
|
||||
|
||||
void CommandData::execute(MasterDevice &m, const StringVector &args)
|
||||
void CommandData::execute(const StringVector &args)
|
||||
{
|
||||
DomainList domains;
|
||||
DomainList::const_iterator di;
|
||||
|
|
@ -74,6 +75,12 @@ void CommandData::execute(MasterDevice &m, const StringVector &args)
|
|||
throwInvalidUsageException(err);
|
||||
}
|
||||
|
||||
if (getMasterIndices().size() != 1) {
|
||||
stringstream err;
|
||||
err << getName() << " requires to select a single master!";
|
||||
throwInvalidUsageException(err);
|
||||
}
|
||||
MasterDevice m(getMasterIndices().front());
|
||||
m.open(MasterDevice::Read);
|
||||
domains = selectedDomains(m);
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class CommandData:
|
|||
CommandData();
|
||||
|
||||
string helpString() const;
|
||||
void execute(MasterDevice &, const StringVector &);
|
||||
void execute(const StringVector &);
|
||||
|
||||
protected:
|
||||
void outputDomainData(MasterDevice &, const ec_ioctl_domain_t &);
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
using namespace std;
|
||||
|
||||
#include "CommandDebug.h"
|
||||
#include "MasterDevice.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
@ -65,7 +66,7 @@ string CommandDebug::helpString() const
|
|||
|
||||
/****************************************************************************/
|
||||
|
||||
void CommandDebug::execute(MasterDevice &m, const StringVector &args)
|
||||
void CommandDebug::execute(const StringVector &args)
|
||||
{
|
||||
stringstream str;
|
||||
int debugLevel;
|
||||
|
|
@ -86,8 +87,13 @@ void CommandDebug::execute(MasterDevice &m, const StringVector &args)
|
|||
throwInvalidUsageException(err);
|
||||
}
|
||||
|
||||
m.open(MasterDevice::ReadWrite);
|
||||
m.setDebug(debugLevel);
|
||||
MasterIndexList::const_iterator mi;
|
||||
for (mi = getMasterIndices().begin();
|
||||
mi != getMasterIndices().end(); mi++) {
|
||||
MasterDevice m(*mi);
|
||||
m.open(MasterDevice::ReadWrite);
|
||||
m.setDebug(debugLevel);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class CommandDebug:
|
|||
CommandDebug();
|
||||
|
||||
string helpString() const;
|
||||
void execute(MasterDevice &, const StringVector &);
|
||||
void execute(const StringVector &);
|
||||
};
|
||||
|
||||
/****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
using namespace std;
|
||||
|
||||
#include "CommandDomains.h"
|
||||
#include "MasterDevice.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
@ -89,10 +90,11 @@ string CommandDomains::helpString() const
|
|||
|
||||
/****************************************************************************/
|
||||
|
||||
void CommandDomains::execute(MasterDevice &m, const StringVector &args)
|
||||
void CommandDomains::execute(const StringVector &args)
|
||||
{
|
||||
DomainList domains;
|
||||
DomainList::const_iterator di;
|
||||
bool doIndent;
|
||||
|
||||
if (args.size()) {
|
||||
stringstream err;
|
||||
|
|
@ -100,11 +102,21 @@ void CommandDomains::execute(MasterDevice &m, const StringVector &args)
|
|||
throwInvalidUsageException(err);
|
||||
}
|
||||
|
||||
m.open(MasterDevice::Read);
|
||||
domains = selectedDomains(m);
|
||||
doIndent = getMasterIndices().size() > 1;
|
||||
MasterIndexList::const_iterator mi;
|
||||
for (mi = getMasterIndices().begin();
|
||||
mi != getMasterIndices().end(); mi++) {
|
||||
MasterDevice m(*mi);
|
||||
m.open(MasterDevice::Read);
|
||||
domains = selectedDomains(m);
|
||||
|
||||
for (di = domains.begin(); di != domains.end(); di++) {
|
||||
showDomain(m, *di);
|
||||
if (doIndent) {
|
||||
cout << "Master" << dec << *mi << endl;
|
||||
}
|
||||
|
||||
for (di = domains.begin(); di != domains.end(); di++) {
|
||||
showDomain(m, *di, doIndent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -112,7 +124,8 @@ void CommandDomains::execute(MasterDevice &m, const StringVector &args)
|
|||
|
||||
void CommandDomains::showDomain(
|
||||
MasterDevice &m,
|
||||
const ec_ioctl_domain_t &domain
|
||||
const ec_ioctl_domain_t &domain,
|
||||
bool doIndent
|
||||
)
|
||||
{
|
||||
unsigned char *processData;
|
||||
|
|
@ -120,8 +133,9 @@ void CommandDomains::showDomain(
|
|||
unsigned int i, j;
|
||||
ec_ioctl_domain_fmmu_t fmmu;
|
||||
unsigned int dataOffset;
|
||||
string indent(doIndent ? " " : "");
|
||||
|
||||
cout << "Domain" << dec << domain.index << ":"
|
||||
cout << indent << "Domain" << dec << domain.index << ":"
|
||||
<< " LogBaseAddr 0x"
|
||||
<< hex << setfill('0')
|
||||
<< setw(8) << domain.logical_base_address
|
||||
|
|
@ -146,7 +160,7 @@ void CommandDomains::showDomain(
|
|||
for (i = 0; i < domain.fmmu_count; i++) {
|
||||
m.getFmmu(&fmmu, domain.index, i);
|
||||
|
||||
cout << " SlaveConfig "
|
||||
cout << indent << " SlaveConfig "
|
||||
<< dec << fmmu.slave_config_alias
|
||||
<< ":" << fmmu.slave_config_position
|
||||
<< ", SM" << (unsigned int) fmmu.sync_index << " ("
|
||||
|
|
@ -165,10 +179,10 @@ void CommandDomains::showDomain(
|
|||
throwCommandException(err);
|
||||
}
|
||||
|
||||
cout << " " << hex << setfill('0');
|
||||
cout << indent << " " << hex << setfill('0');
|
||||
for (j = 0; j < fmmu.data_size; j++) {
|
||||
if (j && !(j % BreakAfterBytes))
|
||||
cout << endl << " ";
|
||||
cout << endl << indent << " ";
|
||||
cout << "0x" << setw(2)
|
||||
<< (unsigned int) *(processData + dataOffset + j) << " ";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,10 +41,10 @@ class CommandDomains:
|
|||
CommandDomains();
|
||||
|
||||
string helpString() const;
|
||||
void execute(MasterDevice &, const StringVector &);
|
||||
void execute(const StringVector &);
|
||||
|
||||
protected:
|
||||
void showDomain(MasterDevice &, const ec_ioctl_domain_t &);
|
||||
void showDomain(MasterDevice &, const ec_ioctl_domain_t &, bool);
|
||||
};
|
||||
|
||||
/****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
using namespace std;
|
||||
|
||||
#include "CommandDownload.h"
|
||||
#include "MasterDevice.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
@ -83,7 +84,7 @@ string CommandDownload::helpString() const
|
|||
|
||||
/****************************************************************************/
|
||||
|
||||
void CommandDownload::execute(MasterDevice &m, const StringVector &args)
|
||||
void CommandDownload::execute(const StringVector &args)
|
||||
{
|
||||
stringstream strIndex, strSubIndex, strValue, err;
|
||||
ec_ioctl_slave_sdo_download_t data;
|
||||
|
|
@ -115,6 +116,11 @@ void CommandDownload::execute(MasterDevice &m, const StringVector &args)
|
|||
}
|
||||
data.sdo_entry_subindex = number;
|
||||
|
||||
if (getMasterIndices().size() != 1) {
|
||||
err << getName() << " requires to select a single master!";
|
||||
throwInvalidUsageException(err);
|
||||
}
|
||||
MasterDevice m(getMasterIndices().front());
|
||||
m.open(MasterDevice::ReadWrite);
|
||||
slaves = selectedSlaves(m);
|
||||
if (slaves.size() != 1) {
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class CommandDownload:
|
|||
CommandDownload();
|
||||
|
||||
string helpString() const;
|
||||
void execute(MasterDevice &, const StringVector &);
|
||||
void execute(const StringVector &);
|
||||
|
||||
protected:
|
||||
enum {DefaultBufferSize = 1024};
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
using namespace std;
|
||||
|
||||
#include "CommandEoe.h"
|
||||
#include "MasterDevice.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
@ -60,11 +61,13 @@ string CommandEoe::helpString() const
|
|||
|
||||
/****************************************************************************/
|
||||
|
||||
void CommandEoe::execute(MasterDevice &m, const StringVector &args)
|
||||
void CommandEoe::execute(const StringVector &args)
|
||||
{
|
||||
ec_ioctl_master_t master;
|
||||
unsigned int i;
|
||||
ec_ioctl_eoe_handler_t eoe;
|
||||
bool doIndent;
|
||||
string indent;
|
||||
|
||||
if (args.size()) {
|
||||
stringstream err;
|
||||
|
|
@ -72,31 +75,42 @@ void CommandEoe::execute(MasterDevice &m, const StringVector &args)
|
|||
throwInvalidUsageException(err);
|
||||
}
|
||||
|
||||
m.open(MasterDevice::Read);
|
||||
m.getMaster(&master);
|
||||
doIndent = getMasterIndices().size();
|
||||
indent = doIndent ? " " : "";
|
||||
MasterIndexList::const_iterator mi;
|
||||
for (mi = getMasterIndices().begin();
|
||||
mi != getMasterIndices().end(); mi++) {
|
||||
MasterDevice m(*mi);
|
||||
m.open(MasterDevice::Read);
|
||||
m.getMaster(&master);
|
||||
|
||||
cout << "Interface Slave State "
|
||||
<< "RxBytes RxRate "
|
||||
<< "TxBytes TxRate TxQueue"
|
||||
<< endl;
|
||||
if (doIndent) {
|
||||
cout << "Master" << dec << *mi << endl;
|
||||
}
|
||||
|
||||
for (i = 0; i < master.eoe_handler_count; i++) {
|
||||
stringstream queue;
|
||||
|
||||
m.getEoeHandler(&eoe, i);
|
||||
|
||||
queue << eoe.tx_queued_frames << "/" << eoe.tx_queue_size;
|
||||
|
||||
cout
|
||||
<< setw(9) << eoe.name << " "
|
||||
<< setw(5) << dec << eoe.slave_position << " "
|
||||
<< setw(5) << (eoe.open ? "up" : "down") << " "
|
||||
<< setw(7) << eoe.rx_bytes << " "
|
||||
<< setw(6) << eoe.rx_rate << " "
|
||||
<< setw(7) << eoe.tx_bytes << " "
|
||||
<< setw(6) << eoe.tx_rate << " "
|
||||
<< setw(7) << queue.str()
|
||||
cout << indent << "Interface Slave State "
|
||||
<< "RxBytes RxRate "
|
||||
<< "TxBytes TxRate TxQueue"
|
||||
<< endl;
|
||||
|
||||
for (i = 0; i < master.eoe_handler_count; i++) {
|
||||
stringstream queue;
|
||||
|
||||
m.getEoeHandler(&eoe, i);
|
||||
|
||||
queue << eoe.tx_queued_frames << "/" << eoe.tx_queue_size;
|
||||
|
||||
cout << indent
|
||||
<< setw(9) << eoe.name << " "
|
||||
<< setw(5) << dec << eoe.slave_position << " "
|
||||
<< setw(5) << (eoe.open ? "up" : "down") << " "
|
||||
<< setw(7) << eoe.rx_bytes << " "
|
||||
<< setw(6) << eoe.rx_rate << " "
|
||||
<< setw(7) << eoe.tx_bytes << " "
|
||||
<< setw(6) << eoe.tx_rate << " "
|
||||
<< setw(7) << queue.str()
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class CommandEoe:
|
|||
CommandEoe();
|
||||
|
||||
string helpString() const;
|
||||
void execute(MasterDevice &, const StringVector &);
|
||||
void execute(const StringVector &);
|
||||
};
|
||||
|
||||
/****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ using namespace std;
|
|||
|
||||
#include "CommandFoeRead.h"
|
||||
#include "foe.h"
|
||||
#include "MasterDevice.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
@ -73,7 +74,7 @@ string CommandFoeRead::helpString() const
|
|||
|
||||
/****************************************************************************/
|
||||
|
||||
void CommandFoeRead::execute(MasterDevice &m, const StringVector &args)
|
||||
void CommandFoeRead::execute(const StringVector &args)
|
||||
{
|
||||
SlaveList slaves;
|
||||
ec_ioctl_slave_t *slave;
|
||||
|
|
@ -86,6 +87,11 @@ void CommandFoeRead::execute(MasterDevice &m, const StringVector &args)
|
|||
throwInvalidUsageException(err);
|
||||
}
|
||||
|
||||
if (getMasterIndices().size() != 1) {
|
||||
err << getName() << " requires to select a single master!";
|
||||
throwInvalidUsageException(err);
|
||||
}
|
||||
MasterDevice m(getMasterIndices().front());
|
||||
m.open(MasterDevice::Read);
|
||||
slaves = selectedSlaves(m);
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class CommandFoeRead:
|
|||
CommandFoeRead();
|
||||
|
||||
string helpString() const;
|
||||
void execute(MasterDevice &, const StringVector &);
|
||||
void execute(const StringVector &);
|
||||
};
|
||||
|
||||
/****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ using namespace std;
|
|||
|
||||
#include "CommandFoeWrite.h"
|
||||
#include "foe.h"
|
||||
#include "MasterDevice.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
@ -79,7 +80,7 @@ string CommandFoeWrite::helpString() const
|
|||
|
||||
/****************************************************************************/
|
||||
|
||||
void CommandFoeWrite::execute(MasterDevice &m, const StringVector &args)
|
||||
void CommandFoeWrite::execute(const StringVector &args)
|
||||
{
|
||||
stringstream err;
|
||||
ec_ioctl_slave_foe_t data;
|
||||
|
|
@ -92,6 +93,12 @@ void CommandFoeWrite::execute(MasterDevice &m, const StringVector &args)
|
|||
throwInvalidUsageException(err);
|
||||
}
|
||||
|
||||
if (getMasterIndices().size() != 1) {
|
||||
err << getName() << " requires to select a single master!";
|
||||
throwInvalidUsageException(err);
|
||||
}
|
||||
MasterDevice m(getMasterIndices().front());
|
||||
|
||||
if (args[0] == "-") {
|
||||
loadFoeData(&data, cin);
|
||||
if (getOutputFile().empty()) {
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class CommandFoeWrite:
|
|||
CommandFoeWrite();
|
||||
|
||||
string helpString() const;
|
||||
void execute(MasterDevice &, const StringVector &);
|
||||
void execute(const StringVector &);
|
||||
|
||||
protected:
|
||||
void loadFoeData(ec_ioctl_slave_foe_t *, const istream &);
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
using namespace std;
|
||||
|
||||
#include "CommandGraph.h"
|
||||
#include "MasterDevice.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
@ -64,7 +65,7 @@ string CommandGraph::helpString() const
|
|||
|
||||
/****************************************************************************/
|
||||
|
||||
void CommandGraph::execute(MasterDevice &m, const StringVector &args)
|
||||
void CommandGraph::execute(const StringVector &args)
|
||||
{
|
||||
ec_ioctl_master_t master;
|
||||
unsigned int i;
|
||||
|
|
@ -89,6 +90,12 @@ void CommandGraph::execute(MasterDevice &m, const StringVector &args)
|
|||
throwInvalidUsageException(err);
|
||||
}
|
||||
|
||||
if (getMasterIndices().size() != 1) {
|
||||
stringstream err;
|
||||
err << getName() << " requires to select a single master!";
|
||||
throwInvalidUsageException(err);
|
||||
}
|
||||
MasterDevice m(getMasterIndices().front());
|
||||
m.open(MasterDevice::Read);
|
||||
m.getMaster(&master);
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class CommandGraph:
|
|||
CommandGraph();
|
||||
|
||||
string helpString() const;
|
||||
void execute(MasterDevice &, const StringVector &);
|
||||
void execute(const StringVector &);
|
||||
};
|
||||
|
||||
/****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
using namespace std;
|
||||
|
||||
#include "CommandMaster.h"
|
||||
#include "MasterDevice.h"
|
||||
|
||||
#define MAX_TIME_STR_SIZE 50
|
||||
|
||||
|
|
@ -53,7 +54,9 @@ string CommandMaster::helpString() const
|
|||
<< getBriefDescription() << endl
|
||||
<< endl
|
||||
<< "Command-specific options:" << endl
|
||||
<< " --master -m <index> Index of the master to use. Default: 0."
|
||||
<< " --master -m <indices> Master indices. A comma-separated" << endl
|
||||
<< " list with ranges is supported." << endl
|
||||
<< " Example: 1,4,5,7-9. Default: - (all)."
|
||||
<< endl << endl
|
||||
<< numericInfo();
|
||||
|
||||
|
|
@ -62,7 +65,7 @@ string CommandMaster::helpString() const
|
|||
|
||||
/****************************************************************************/
|
||||
|
||||
void CommandMaster::execute(MasterDevice &m, const StringVector &args)
|
||||
void CommandMaster::execute(const StringVector &args)
|
||||
{
|
||||
ec_ioctl_master_t data;
|
||||
stringstream err;
|
||||
|
|
@ -76,67 +79,79 @@ void CommandMaster::execute(MasterDevice &m, const StringVector &args)
|
|||
throwInvalidUsageException(err);
|
||||
}
|
||||
|
||||
m.open(MasterDevice::Read);
|
||||
m.getMaster(&data);
|
||||
MasterIndexList::const_iterator mi;
|
||||
for (mi = getMasterIndices().begin();
|
||||
mi != getMasterIndices().end(); mi++) {
|
||||
MasterDevice m(*mi);
|
||||
m.open(MasterDevice::Read);
|
||||
m.getMaster(&data);
|
||||
|
||||
cout
|
||||
<< "Master" << m.getIndex() << endl
|
||||
<< " Phase: ";
|
||||
cout
|
||||
<< "Master" << m.getIndex() << endl
|
||||
<< " Phase: ";
|
||||
|
||||
switch (data.phase) {
|
||||
case 0: cout << "Waiting for device..."; break;
|
||||
case 1: cout << "Idle"; break;
|
||||
case 2: cout << "Operation"; break;
|
||||
default: cout << "???";
|
||||
}
|
||||
|
||||
cout << endl
|
||||
<< " Active: " << (data.active ? "yes" : "no") << endl
|
||||
<< " Slaves: " << data.slave_count << endl
|
||||
<< " Ethernet devices:" << endl;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
cout << " " << (i == 0 ? "Main" : "Backup") << ": ";
|
||||
if (data.devices[i].address[0] == 0x00
|
||||
&& data.devices[i].address[1] == 0x00
|
||||
&& data.devices[i].address[2] == 0x00
|
||||
&& data.devices[i].address[3] == 0x00
|
||||
&& data.devices[i].address[4] == 0x00
|
||||
&& data.devices[i].address[5] == 0x00) {
|
||||
cout << "None.";
|
||||
} else {
|
||||
cout << hex << setfill('0')
|
||||
<< setw(2) << (unsigned int) data.devices[i].address[0] << ":"
|
||||
<< setw(2) << (unsigned int) data.devices[i].address[1] << ":"
|
||||
<< setw(2) << (unsigned int) data.devices[i].address[2] << ":"
|
||||
<< setw(2) << (unsigned int) data.devices[i].address[3] << ":"
|
||||
<< setw(2) << (unsigned int) data.devices[i].address[4] << ":"
|
||||
<< setw(2) << (unsigned int) data.devices[i].address[5] << " ("
|
||||
<< (data.devices[i].attached ? "attached" : "waiting...")
|
||||
<< ")" << endl << dec
|
||||
<< " Link: " << (data.devices[i].link_state ? "UP" : "DOWN") << endl
|
||||
<< " Tx count: " << data.devices[i].tx_count << endl
|
||||
<< " Rx count: " << data.devices[i].rx_count;
|
||||
switch (data.phase) {
|
||||
case 0: cout << "Waiting for device..."; break;
|
||||
case 1: cout << "Idle"; break;
|
||||
case 2: cout << "Operation"; break;
|
||||
default: cout << "???";
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
cout << " Distributed clocks:" << endl
|
||||
<< " Reference clock: ";
|
||||
if (data.ref_clock != 0xffff) {
|
||||
cout << "Slave " << dec << data.ref_clock;
|
||||
} else {
|
||||
cout << "None";
|
||||
}
|
||||
cout << endl
|
||||
<< " Application time: " << data.app_time << endl
|
||||
<< " ";
|
||||
cout << endl
|
||||
<< " Active: " << (data.active ? "yes" : "no") << endl
|
||||
<< " Slaves: " << data.slave_count << endl
|
||||
<< " Ethernet devices:" << endl;
|
||||
|
||||
epoch = data.app_time / 1000000000 + 946684800ULL;
|
||||
time_str_size = strftime(time_str, MAX_TIME_STR_SIZE,
|
||||
"%Y-%m-%d %H:%M:%S", gmtime(&epoch));
|
||||
cout << string(time_str, time_str_size) << "."
|
||||
<< setfill('0') << setw(9) << data.app_time % 1000000000 << endl;
|
||||
for (i = 0; i < 2; i++) {
|
||||
cout << " " << (i == 0 ? "Main" : "Backup") << ": ";
|
||||
if (data.devices[i].address[0] == 0x00
|
||||
&& data.devices[i].address[1] == 0x00
|
||||
&& data.devices[i].address[2] == 0x00
|
||||
&& data.devices[i].address[3] == 0x00
|
||||
&& data.devices[i].address[4] == 0x00
|
||||
&& data.devices[i].address[5] == 0x00) {
|
||||
cout << "None.";
|
||||
} else {
|
||||
cout << hex << setfill('0')
|
||||
<< setw(2) << (unsigned int) data.devices[i].address[0]
|
||||
<< ":"
|
||||
<< setw(2) << (unsigned int) data.devices[i].address[1]
|
||||
<< ":"
|
||||
<< setw(2) << (unsigned int) data.devices[i].address[2]
|
||||
<< ":"
|
||||
<< setw(2) << (unsigned int) data.devices[i].address[3]
|
||||
<< ":"
|
||||
<< setw(2) << (unsigned int) data.devices[i].address[4]
|
||||
<< ":"
|
||||
<< setw(2) << (unsigned int) data.devices[i].address[5]
|
||||
<< " ("
|
||||
<< (data.devices[i].attached ? "attached" : "waiting...")
|
||||
<< ")" << endl << dec
|
||||
<< " Link: "
|
||||
<< (data.devices[i].link_state ? "UP" : "DOWN") << endl
|
||||
<< " Tx count: " << data.devices[i].tx_count << endl
|
||||
<< " Rx count: " << data.devices[i].rx_count;
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
cout << " Distributed clocks:" << endl
|
||||
<< " Reference clock: ";
|
||||
if (data.ref_clock != 0xffff) {
|
||||
cout << "Slave " << dec << data.ref_clock;
|
||||
} else {
|
||||
cout << "None";
|
||||
}
|
||||
cout << endl
|
||||
<< " Application time: " << data.app_time << endl
|
||||
<< " ";
|
||||
|
||||
epoch = data.app_time / 1000000000 + 946684800ULL;
|
||||
time_str_size = strftime(time_str, MAX_TIME_STR_SIZE,
|
||||
"%Y-%m-%d %H:%M:%S", gmtime(&epoch));
|
||||
cout << string(time_str, time_str_size) << "."
|
||||
<< setfill('0') << setw(9) << data.app_time % 1000000000 << endl;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class CommandMaster:
|
|||
CommandMaster();
|
||||
|
||||
string helpString() const;
|
||||
void execute(MasterDevice &, const StringVector &);
|
||||
void execute(const StringVector &);
|
||||
};
|
||||
|
||||
/****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
using namespace std;
|
||||
|
||||
#include "CommandPdos.h"
|
||||
#include "MasterDevice.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
@ -88,11 +89,11 @@ string CommandPdos::helpString() const
|
|||
|
||||
/****************************************************************************/
|
||||
|
||||
void CommandPdos::execute(MasterDevice &m, const StringVector &args)
|
||||
void CommandPdos::execute(const StringVector &args)
|
||||
{
|
||||
SlaveList slaves;
|
||||
SlaveList::const_iterator si;
|
||||
bool showHeader;
|
||||
bool showHeader, multiMaster;
|
||||
|
||||
if (args.size()) {
|
||||
stringstream err;
|
||||
|
|
@ -100,12 +101,18 @@ void CommandPdos::execute(MasterDevice &m, const StringVector &args)
|
|||
throwInvalidUsageException(err);
|
||||
}
|
||||
|
||||
m.open(MasterDevice::Read);
|
||||
slaves = selectedSlaves(m);
|
||||
showHeader = slaves.size() > 1;
|
||||
multiMaster = getMasterIndices().size() > 1;
|
||||
MasterIndexList::const_iterator mi;
|
||||
for (mi = getMasterIndices().begin();
|
||||
mi != getMasterIndices().end(); mi++) {
|
||||
MasterDevice m(*mi);
|
||||
m.open(MasterDevice::Read);
|
||||
slaves = selectedSlaves(m);
|
||||
showHeader = multiMaster || slaves.size() > 1;
|
||||
|
||||
for (si = slaves.begin(); si != slaves.end(); si++) {
|
||||
listSlavePdos(m, *si, showHeader);
|
||||
for (si = slaves.begin(); si != slaves.end(); si++) {
|
||||
listSlavePdos(m, *si, showHeader);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -123,7 +130,8 @@ void CommandPdos::listSlavePdos(
|
|||
unsigned int i, j, k;
|
||||
|
||||
if (showHeader)
|
||||
cout << "=== Slave " << slave.position << " ===" << endl;
|
||||
cout << "=== Master " << m.getIndex()
|
||||
<< ", Slave " << slave.position << " ===" << endl;
|
||||
|
||||
for (i = 0; i < slave.sync_count; i++) {
|
||||
m.getSync(&sync, slave.position, i);
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class CommandPdos:
|
|||
CommandPdos();
|
||||
|
||||
string helpString() const;
|
||||
void execute(MasterDevice &, const StringVector &);
|
||||
void execute(const StringVector &);
|
||||
|
||||
protected:
|
||||
void listSlavePdos(MasterDevice &, const ec_ioctl_slave_t &, bool);
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
using namespace std;
|
||||
|
||||
#include "CommandRegRead.h"
|
||||
#include "MasterDevice.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
@ -78,7 +79,7 @@ string CommandRegRead::helpString() const
|
|||
|
||||
/****************************************************************************/
|
||||
|
||||
void CommandRegRead::execute(MasterDevice &m, const StringVector &args)
|
||||
void CommandRegRead::execute(const StringVector &args)
|
||||
{
|
||||
SlaveList slaves;
|
||||
ec_ioctl_slave_reg_t data;
|
||||
|
|
@ -141,6 +142,11 @@ void CommandRegRead::execute(MasterDevice &m, const StringVector &args)
|
|||
throwInvalidUsageException(err);
|
||||
}
|
||||
|
||||
if (getMasterIndices().size() != 1) {
|
||||
err << getName() << " requires to select a single master!";
|
||||
throwInvalidUsageException(err);
|
||||
}
|
||||
MasterDevice m(getMasterIndices().front());
|
||||
m.open(MasterDevice::Read);
|
||||
slaves = selectedSlaves(m);
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class CommandRegRead:
|
|||
CommandRegRead();
|
||||
|
||||
string helpString() const;
|
||||
void execute(MasterDevice &, const StringVector &);
|
||||
void execute(const StringVector &);
|
||||
};
|
||||
|
||||
/****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ using namespace std;
|
|||
|
||||
#include "CommandRegWrite.h"
|
||||
#include "sii_crc.h"
|
||||
#include "MasterDevice.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
@ -80,7 +81,7 @@ string CommandRegWrite::helpString() const
|
|||
|
||||
/****************************************************************************/
|
||||
|
||||
void CommandRegWrite::execute(MasterDevice &m, const StringVector &args)
|
||||
void CommandRegWrite::execute(const StringVector &args)
|
||||
{
|
||||
stringstream strOffset, err;
|
||||
ec_ioctl_slave_reg_t data;
|
||||
|
|
@ -100,6 +101,12 @@ void CommandRegWrite::execute(MasterDevice &m, const StringVector &args)
|
|||
err << "Invalid offset '" << args[0] << "'!";
|
||||
throwInvalidUsageException(err);
|
||||
}
|
||||
|
||||
if (getMasterIndices().size() != 1) {
|
||||
err << getName() << " requires to select a single master!";
|
||||
throwInvalidUsageException(err);
|
||||
}
|
||||
MasterDevice m(getMasterIndices().front());
|
||||
|
||||
if (getDataType().empty()) {
|
||||
if (args[1] == "-") {
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class CommandRegWrite:
|
|||
CommandRegWrite();
|
||||
|
||||
string helpString() const;
|
||||
void execute(MasterDevice &, const StringVector &);
|
||||
void execute(const StringVector &);
|
||||
|
||||
private:
|
||||
void loadRegData(ec_ioctl_slave_reg_t *, const istream &);
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
using namespace std;
|
||||
|
||||
#include "CommandSdos.h"
|
||||
#include "MasterDevice.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
@ -86,11 +87,11 @@ string CommandSdos::helpString() const
|
|||
|
||||
/****************************************************************************/
|
||||
|
||||
void CommandSdos::execute(MasterDevice &m, const StringVector &args)
|
||||
void CommandSdos::execute(const StringVector &args)
|
||||
{
|
||||
SlaveList slaves;
|
||||
SlaveList::const_iterator si;
|
||||
bool showHeader;
|
||||
bool showHeader, multiMaster;
|
||||
|
||||
if (args.size()) {
|
||||
stringstream err;
|
||||
|
|
@ -98,12 +99,18 @@ void CommandSdos::execute(MasterDevice &m, const StringVector &args)
|
|||
throwInvalidUsageException(err);
|
||||
}
|
||||
|
||||
m.open(MasterDevice::Read);
|
||||
slaves = selectedSlaves(m);
|
||||
showHeader = slaves.size() > 1;
|
||||
multiMaster = getMasterIndices().size() > 1;
|
||||
MasterIndexList::const_iterator mi;
|
||||
for (mi = getMasterIndices().begin();
|
||||
mi != getMasterIndices().end(); mi++) {
|
||||
MasterDevice m(*mi);
|
||||
m.open(MasterDevice::Read);
|
||||
slaves = selectedSlaves(m);
|
||||
showHeader = multiMaster || slaves.size() > 1;
|
||||
|
||||
for (si = slaves.begin(); si != slaves.end(); si++) {
|
||||
listSlaveSdos(m, *si, showHeader);
|
||||
for (si = slaves.begin(); si != slaves.end(); si++) {
|
||||
listSlaveSdos(m, *si, showHeader);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -121,7 +128,8 @@ void CommandSdos::listSlaveSdos(
|
|||
const DataType *d;
|
||||
|
||||
if (showHeader)
|
||||
cout << "=== Slave " << slave.position << " ===" << endl;
|
||||
cout << "=== Master " << m.getIndex()
|
||||
<< ", Slave " << slave.position << " ===" << endl;
|
||||
|
||||
for (i = 0; i < slave.sdo_count; i++) {
|
||||
m.getSdo(&sdo, slave.position, i);
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class CommandSdos:
|
|||
CommandSdos();
|
||||
|
||||
string helpString() const;
|
||||
void execute(MasterDevice &, const StringVector &);
|
||||
void execute(const StringVector &);
|
||||
|
||||
protected:
|
||||
void listSlaveSdos(MasterDevice &, const ec_ioctl_slave_t &, bool);
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
using namespace std;
|
||||
|
||||
#include "CommandSiiRead.h"
|
||||
#include "MasterDevice.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
@ -73,7 +74,7 @@ string CommandSiiRead::helpString() const
|
|||
|
||||
/****************************************************************************/
|
||||
|
||||
void CommandSiiRead::execute(MasterDevice &m, const StringVector &args)
|
||||
void CommandSiiRead::execute(const StringVector &args)
|
||||
{
|
||||
SlaveList slaves;
|
||||
ec_ioctl_slave_t *slave;
|
||||
|
|
@ -88,6 +89,11 @@ void CommandSiiRead::execute(MasterDevice &m, const StringVector &args)
|
|||
throwInvalidUsageException(err);
|
||||
}
|
||||
|
||||
if (getMasterIndices().size() != 1) {
|
||||
err << getName() << " requires to select a single master!";
|
||||
throwInvalidUsageException(err);
|
||||
}
|
||||
MasterDevice m(getMasterIndices().front());
|
||||
m.open(MasterDevice::Read);
|
||||
slaves = selectedSlaves(m);
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class CommandSiiRead:
|
|||
CommandSiiRead();
|
||||
|
||||
string helpString() const;
|
||||
void execute(MasterDevice &, const StringVector &);
|
||||
void execute(const StringVector &);
|
||||
|
||||
protected:
|
||||
struct CategoryName {
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ using namespace std;
|
|||
|
||||
#include "CommandSiiWrite.h"
|
||||
#include "sii_crc.h"
|
||||
#include "MasterDevice.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
@ -75,7 +76,7 @@ string CommandSiiWrite::helpString() const
|
|||
|
||||
/****************************************************************************/
|
||||
|
||||
void CommandSiiWrite::execute(MasterDevice &m, const StringVector &args)
|
||||
void CommandSiiWrite::execute(const StringVector &args)
|
||||
{
|
||||
stringstream err;
|
||||
ec_ioctl_slave_sii_t data;
|
||||
|
|
@ -87,6 +88,12 @@ void CommandSiiWrite::execute(MasterDevice &m, const StringVector &args)
|
|||
throwInvalidUsageException(err);
|
||||
}
|
||||
|
||||
if (getMasterIndices().size() != 1) {
|
||||
err << getName() << " requires to select a single master!";
|
||||
throwInvalidUsageException(err);
|
||||
}
|
||||
MasterDevice m(getMasterIndices().front());
|
||||
|
||||
if (args[0] == "-") {
|
||||
loadSiiData(&data, cin);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class CommandSiiWrite:
|
|||
CommandSiiWrite();
|
||||
|
||||
string helpString() const;
|
||||
void execute(MasterDevice &, const StringVector &);
|
||||
void execute(const StringVector &);
|
||||
|
||||
protected:
|
||||
void loadSiiData(ec_ioctl_slave_sii_t *, const istream &);
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
using namespace std;
|
||||
|
||||
#include "CommandSlaves.h"
|
||||
#include "MasterDevice.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
@ -105,9 +106,10 @@ string CommandSlaves::helpString() const
|
|||
|
||||
/****************************************************************************/
|
||||
|
||||
void CommandSlaves::execute(MasterDevice &m, const StringVector &args)
|
||||
void CommandSlaves::execute(const StringVector &args)
|
||||
{
|
||||
SlaveList slaves;
|
||||
bool doIndent;
|
||||
|
||||
if (args.size()) {
|
||||
stringstream err;
|
||||
|
|
@ -115,13 +117,23 @@ void CommandSlaves::execute(MasterDevice &m, const StringVector &args)
|
|||
throwInvalidUsageException(err);
|
||||
}
|
||||
|
||||
m.open(MasterDevice::Read);
|
||||
slaves = selectedSlaves(m);
|
||||
doIndent = getMasterIndices().size() > 1;
|
||||
MasterIndexList::const_iterator mi;
|
||||
for (mi = getMasterIndices().begin();
|
||||
mi != getMasterIndices().end(); mi++) {
|
||||
MasterDevice m(*mi);
|
||||
m.open(MasterDevice::Read);
|
||||
slaves = selectedSlaves(m);
|
||||
|
||||
if (getVerbosity() == Verbose) {
|
||||
showSlaves(m, slaves);
|
||||
} else {
|
||||
listSlaves(m, slaves);
|
||||
if (doIndent) {
|
||||
cout << "Master" << dec << *mi << endl;
|
||||
}
|
||||
|
||||
if (getVerbosity() == Verbose) {
|
||||
showSlaves(m, slaves);
|
||||
} else {
|
||||
listSlaves(m, slaves, doIndent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -129,7 +141,8 @@ void CommandSlaves::execute(MasterDevice &m, const StringVector &args)
|
|||
|
||||
void CommandSlaves::listSlaves(
|
||||
MasterDevice &m,
|
||||
const SlaveList &slaves
|
||||
const SlaveList &slaves,
|
||||
bool doIndent
|
||||
)
|
||||
{
|
||||
ec_ioctl_master_t master;
|
||||
|
|
@ -143,6 +156,7 @@ void CommandSlaves::listSlaves(
|
|||
stringstream str;
|
||||
unsigned int maxPosWidth = 0, maxAliasWidth = 0,
|
||||
maxRelPosWidth = 0, maxStateWidth = 0;
|
||||
string indent(doIndent ? " " : "");
|
||||
|
||||
m.getMaster(&master);
|
||||
|
||||
|
|
@ -200,7 +214,7 @@ void CommandSlaves::listSlaves(
|
|||
}
|
||||
|
||||
for (iter = infoList.begin(); iter != infoList.end(); iter++) {
|
||||
cout << setfill(' ') << right
|
||||
cout << indent << setfill(' ') << right
|
||||
<< setw(maxPosWidth) << iter->pos << " "
|
||||
<< setw(maxAliasWidth) << iter->alias
|
||||
<< ":" << left
|
||||
|
|
@ -222,7 +236,8 @@ void CommandSlaves::showSlaves(
|
|||
int i;
|
||||
|
||||
for (si = slaves.begin(); si != slaves.end(); si++) {
|
||||
cout << "=== Slave " << dec << si->position << " ===" << endl;
|
||||
cout << "=== Master " << dec << m.getIndex()
|
||||
<< ", Slave " << dec << si->position << " ===" << endl;
|
||||
|
||||
if (si->alias)
|
||||
cout << "Alias: " << si->alias << endl;
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class CommandSlaves:
|
|||
CommandSlaves();
|
||||
|
||||
string helpString() const;
|
||||
void execute(MasterDevice &, const StringVector &);
|
||||
void execute(const StringVector &);
|
||||
|
||||
protected:
|
||||
struct Info {
|
||||
|
|
@ -53,7 +53,7 @@ class CommandSlaves:
|
|||
string name;
|
||||
};
|
||||
|
||||
void listSlaves(MasterDevice &, const SlaveList &);
|
||||
void listSlaves(MasterDevice &, const SlaveList &, bool);
|
||||
void showSlaves(MasterDevice &, const SlaveList &);
|
||||
|
||||
static bool slaveInList( const ec_ioctl_slave_t &, const SlaveList &);
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
using namespace std;
|
||||
|
||||
#include "CommandStates.h"
|
||||
#include "MasterDevice.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
@ -65,7 +66,7 @@ string CommandStates::helpString() const
|
|||
|
||||
/****************************************************************************/
|
||||
|
||||
void CommandStates::execute(MasterDevice &m, const StringVector &args)
|
||||
void CommandStates::execute(const StringVector &args)
|
||||
{
|
||||
SlaveList slaves;
|
||||
SlaveList::const_iterator si;
|
||||
|
|
@ -97,15 +98,16 @@ void CommandStates::execute(MasterDevice &m, const StringVector &args)
|
|||
throwInvalidUsageException(err);
|
||||
}
|
||||
|
||||
m.open(MasterDevice::ReadWrite);
|
||||
slaves = selectedSlaves(m);
|
||||
MasterIndexList::const_iterator mi;
|
||||
for (mi = getMasterIndices().begin();
|
||||
mi != getMasterIndices().end(); mi++) {
|
||||
MasterDevice m(*mi);
|
||||
m.open(MasterDevice::ReadWrite);
|
||||
slaves = selectedSlaves(m);
|
||||
|
||||
if (!slaves.size() && getVerbosity() != Quiet) {
|
||||
cerr << "Warning: Selection matches no slaves!" << endl;
|
||||
}
|
||||
|
||||
for (si = slaves.begin(); si != slaves.end(); si++) {
|
||||
m.requestState(si->position, state);
|
||||
for (si = slaves.begin(); si != slaves.end(); si++) {
|
||||
m.requestState(si->position, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class CommandStates:
|
|||
CommandStates();
|
||||
|
||||
string helpString() const;
|
||||
void execute(MasterDevice &, const StringVector &);
|
||||
void execute(const StringVector &);
|
||||
};
|
||||
|
||||
/****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
using namespace std;
|
||||
|
||||
#include "CommandUpload.h"
|
||||
#include "MasterDevice.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
@ -81,7 +82,7 @@ string CommandUpload::helpString() const
|
|||
|
||||
/****************************************************************************/
|
||||
|
||||
void CommandUpload::execute(MasterDevice &m, const StringVector &args)
|
||||
void CommandUpload::execute(const StringVector &args)
|
||||
{
|
||||
SlaveList slaves;
|
||||
stringstream err, strIndex, strSubIndex;
|
||||
|
|
@ -113,6 +114,11 @@ void CommandUpload::execute(MasterDevice &m, const StringVector &args)
|
|||
}
|
||||
data.sdo_entry_subindex = uval;
|
||||
|
||||
if (getMasterIndices().size() != 1) {
|
||||
err << getName() << " requires to select a single master!";
|
||||
throwInvalidUsageException(err);
|
||||
}
|
||||
MasterDevice m(getMasterIndices().front());
|
||||
m.open(MasterDevice::Read);
|
||||
slaves = selectedSlaves(m);
|
||||
if (slaves.size() != 1) {
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class CommandUpload:
|
|||
CommandUpload();
|
||||
|
||||
string helpString() const;
|
||||
void execute(MasterDevice &, const StringVector &);
|
||||
void execute(const StringVector &);
|
||||
|
||||
protected:
|
||||
enum {DefaultBufferSize = 64 * 1024};
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ string CommandVersion::helpString() const
|
|||
|
||||
/****************************************************************************/
|
||||
|
||||
void CommandVersion::execute(MasterDevice &m, const StringVector &args)
|
||||
void CommandVersion::execute(const StringVector &args)
|
||||
{
|
||||
if (args.size()) {
|
||||
stringstream err;
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class CommandVersion:
|
|||
CommandVersion();
|
||||
|
||||
string helpString() const;
|
||||
void execute(MasterDevice &, const StringVector &);
|
||||
void execute(const StringVector &);
|
||||
};
|
||||
|
||||
/****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
using namespace std;
|
||||
|
||||
#include "CommandXml.h"
|
||||
#include "MasterDevice.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
@ -68,7 +69,7 @@ string CommandXml::helpString() const
|
|||
|
||||
/****************************************************************************/
|
||||
|
||||
void CommandXml::execute(MasterDevice &m, const StringVector &args)
|
||||
void CommandXml::execute(const StringVector &args)
|
||||
{
|
||||
SlaveList slaves;
|
||||
SlaveList::const_iterator si;
|
||||
|
|
@ -79,6 +80,12 @@ void CommandXml::execute(MasterDevice &m, const StringVector &args)
|
|||
throwInvalidUsageException(err);
|
||||
}
|
||||
|
||||
if (getMasterIndices().size() != 1) {
|
||||
stringstream err;
|
||||
err << getName() << " requires to select a single master!";
|
||||
throwInvalidUsageException(err);
|
||||
}
|
||||
MasterDevice m(getMasterIndices().front());
|
||||
m.open(MasterDevice::Read);
|
||||
slaves = selectedSlaves(m);
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class CommandXml:
|
|||
CommandXml();
|
||||
|
||||
string helpString() const;
|
||||
void execute(MasterDevice &, const StringVector &);
|
||||
void execute(const StringVector &);
|
||||
|
||||
protected:
|
||||
void generateSlaveXml(MasterDevice &, const ec_ioctl_slave_t &,
|
||||
|
|
|
|||
|
|
@ -38,8 +38,8 @@ bin_PROGRAMS = ethercat
|
|||
ethercat_SOURCES = \
|
||||
Command.cpp \
|
||||
CommandAlias.cpp \
|
||||
CommandConfig.cpp \
|
||||
CommandCStruct.cpp \
|
||||
CommandConfig.cpp \
|
||||
CommandData.cpp \
|
||||
CommandDebug.cpp \
|
||||
CommandDomains.cpp \
|
||||
|
|
@ -62,6 +62,7 @@ ethercat_SOURCES = \
|
|||
CommandXml.cpp \
|
||||
FoeCommand.cpp \
|
||||
MasterDevice.cpp \
|
||||
NumberListParser.cpp \
|
||||
SdoCommand.cpp \
|
||||
main.cpp \
|
||||
sii_crc.cpp
|
||||
|
|
@ -75,8 +76,8 @@ endif
|
|||
noinst_HEADERS = \
|
||||
Command.h \
|
||||
CommandAlias.h \
|
||||
CommandConfig.h \
|
||||
CommandCStruct.h \
|
||||
CommandConfig.h \
|
||||
CommandData.h \
|
||||
CommandDebug.h \
|
||||
CommandDomains.h \
|
||||
|
|
@ -99,6 +100,7 @@ noinst_HEADERS = \
|
|||
CommandXml.h \
|
||||
FoeCommand.h \
|
||||
MasterDevice.h \
|
||||
NumberListParser.h \
|
||||
SdoCommand.h \
|
||||
sii_crc.h
|
||||
|
||||
|
|
|
|||
|
|
@ -42,10 +42,11 @@ using namespace std;
|
|||
|
||||
/****************************************************************************/
|
||||
|
||||
MasterDevice::MasterDevice()
|
||||
MasterDevice::MasterDevice(unsigned int index):
|
||||
index(index),
|
||||
masterCount(0U),
|
||||
fd(-1)
|
||||
{
|
||||
index = 0;
|
||||
fd = -1;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
|
@ -69,6 +70,7 @@ void MasterDevice::open(Permissions perm)
|
|||
stringstream deviceName;
|
||||
|
||||
if (fd == -1) { // not already open
|
||||
ec_ioctl_module_t module_data;
|
||||
deviceName << "/dev/EtherCAT" << index;
|
||||
|
||||
if ((fd = ::open(deviceName.str().c_str(),
|
||||
|
|
@ -78,6 +80,16 @@ void MasterDevice::open(Permissions perm)
|
|||
<< strerror(errno);
|
||||
throw MasterDeviceException(err);
|
||||
}
|
||||
|
||||
getModule(&module_data);
|
||||
if (module_data.ioctl_version_magic != EC_IOCTL_VERSION_MAGIC) {
|
||||
stringstream err;
|
||||
err << "ioctl() version magic is differing: "
|
||||
<< deviceName << ": " << module_data.ioctl_version_magic
|
||||
<< ", ethercat tool: " << EC_IOCTL_VERSION_MAGIC;
|
||||
throw MasterDeviceException(err);
|
||||
}
|
||||
masterCount = module_data.master_count;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -93,6 +105,17 @@ void MasterDevice::close()
|
|||
|
||||
/****************************************************************************/
|
||||
|
||||
void MasterDevice::getModule(ec_ioctl_module_t *data)
|
||||
{
|
||||
if (ioctl(fd, EC_IOCTL_MODULE, data) < 0) {
|
||||
stringstream err;
|
||||
err << "Failed to get module information: " << strerror(errno);
|
||||
throw MasterDeviceException(err);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
void MasterDevice::getMaster(ec_ioctl_master_t *data)
|
||||
{
|
||||
if (ioctl(fd, EC_IOCTL_MASTER, data) < 0) {
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ class MasterDeviceSdoAbortException:
|
|||
class MasterDevice
|
||||
{
|
||||
public:
|
||||
MasterDevice();
|
||||
MasterDevice(unsigned int = 0U);
|
||||
~MasterDevice();
|
||||
|
||||
void setIndex(unsigned int);
|
||||
|
|
@ -89,6 +89,8 @@ class MasterDevice
|
|||
void open(Permissions);
|
||||
void close();
|
||||
|
||||
void getModule(ec_ioctl_module_t *);
|
||||
|
||||
void getMaster(ec_ioctl_master_t *);
|
||||
void getConfig(ec_ioctl_config_t *, unsigned int);
|
||||
void getConfigPdo(ec_ioctl_config_pdo_t *, unsigned int, uint8_t,
|
||||
|
|
@ -121,8 +123,11 @@ class MasterDevice
|
|||
void getEoeHandler(ec_ioctl_eoe_handler_t *, uint16_t);
|
||||
#endif
|
||||
|
||||
unsigned int getMasterCount() const {return masterCount;}
|
||||
|
||||
private:
|
||||
unsigned int index;
|
||||
unsigned int masterCount;
|
||||
int fd;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,230 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2006-2009 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 version 2, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* 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 license mentioned above concerns the source code only. Using the
|
||||
* EtherCAT technology and brand is only permitted in compliance with the
|
||||
* industrial property and similar rights of Beckhoff Automation GmbH.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include <cstring>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
using namespace std;
|
||||
|
||||
#include "NumberListParser.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
NumberListParser::NumberListParser():
|
||||
max(0U),
|
||||
hasMax(false)
|
||||
{
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
NumberListParser::~NumberListParser()
|
||||
{
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
NumberListParser::NumberList NumberListParser::parse(const char *data)
|
||||
{
|
||||
NumberList ret;
|
||||
unsigned int i = 0, size = strlen(data), firstNum = 0U, secondNum = 0U;
|
||||
typedef enum {
|
||||
SectionStart,
|
||||
FirstNumber,
|
||||
Range,
|
||||
SecondNumber,
|
||||
Finished
|
||||
} State;
|
||||
State state = SectionStart;
|
||||
|
||||
while (state != Finished) {
|
||||
switch (state) {
|
||||
case SectionStart:
|
||||
if (i >= size) {
|
||||
state = Finished;
|
||||
} else if (isNumeric(data[i])) {
|
||||
firstNum = parseNumber(data, &i, size);
|
||||
state = FirstNumber;
|
||||
} else if (data[i] == '-') {
|
||||
firstNum = 0U;
|
||||
i++;
|
||||
state = Range;
|
||||
} else if (data[i] == ',') {
|
||||
i++;
|
||||
} else {
|
||||
stringstream err;
|
||||
err << "Invalid character " << data[i]
|
||||
<< " at position " << i << "in state "
|
||||
<< state << "." << endl;
|
||||
throw runtime_error(err.str());
|
||||
}
|
||||
break;
|
||||
|
||||
case FirstNumber:
|
||||
if (i >= size) {
|
||||
ret.push_back(firstNum);
|
||||
state = Finished;
|
||||
} else if (data[i] == '-') {
|
||||
i++;
|
||||
state = Range;
|
||||
} else if (data[i] == ',') {
|
||||
i++;
|
||||
ret.push_back(firstNum);
|
||||
state = SectionStart;
|
||||
} else {
|
||||
stringstream err;
|
||||
err << "Invalid character " << data[i]
|
||||
<< " at position " << i << "in state "
|
||||
<< state << "." << endl;
|
||||
throw runtime_error(err.str());
|
||||
}
|
||||
break;
|
||||
|
||||
case Range:
|
||||
if (i >= size) {
|
||||
secondNum = maximum();
|
||||
NumberList r = range(firstNum, secondNum);
|
||||
ret.splice(ret.end(), r);
|
||||
state = Finished;
|
||||
} else if (isNumeric(data[i])) {
|
||||
secondNum = parseNumber(data, &i, size);
|
||||
state = SecondNumber;
|
||||
} else if (data[i] == ',') {
|
||||
i++;
|
||||
secondNum = maximum();
|
||||
NumberList r = range(firstNum, secondNum);
|
||||
ret.splice(ret.end(), r);
|
||||
state = SectionStart;
|
||||
} else {
|
||||
stringstream err;
|
||||
err << "Invalid character " << data[i]
|
||||
<< " at position " << i << "in state "
|
||||
<< state << "." << endl;
|
||||
throw runtime_error(err.str());
|
||||
}
|
||||
break;
|
||||
|
||||
case SecondNumber:
|
||||
if (i >= size) {
|
||||
NumberList r = range(firstNum, secondNum);
|
||||
ret.splice(ret.end(), r);
|
||||
state = Finished;
|
||||
} else if (data[i] == ',') {
|
||||
i++;
|
||||
NumberList r = range(firstNum, secondNum);
|
||||
ret.splice(ret.end(), r);
|
||||
state = SectionStart;
|
||||
} else {
|
||||
stringstream err;
|
||||
err << "Invalid character " << data[i]
|
||||
<< " at position " << i << "in state "
|
||||
<< state << "." << endl;
|
||||
throw runtime_error(err.str());
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
stringstream err;
|
||||
err << "Invalid state " << state << ".";
|
||||
throw runtime_error(err.str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
unsigned int NumberListParser::maximum()
|
||||
{
|
||||
if (!hasMax) {
|
||||
max = getMax();
|
||||
}
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
bool NumberListParser::isNumeric(char c)
|
||||
{
|
||||
return c >= '0' && c <= '9';
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
unsigned int NumberListParser::parseNumber(
|
||||
const char *data,
|
||||
unsigned int *i,
|
||||
unsigned int size
|
||||
)
|
||||
{
|
||||
unsigned int numSize = 0U, ret;
|
||||
|
||||
while (*i + numSize < size && isNumeric(data[*i + numSize])) {
|
||||
numSize++;
|
||||
}
|
||||
|
||||
if (numSize) {
|
||||
stringstream str;
|
||||
str << string(data + *i, numSize);
|
||||
str >> ret;
|
||||
} else {
|
||||
throw runtime_error("EOF");
|
||||
}
|
||||
|
||||
*i = *i + numSize;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
NumberListParser::NumberList NumberListParser::range(
|
||||
unsigned int i,
|
||||
unsigned int j
|
||||
)
|
||||
{
|
||||
NumberList ret;
|
||||
|
||||
if (i <= j) {
|
||||
for (; i <= j; i++) {
|
||||
ret.push_back(i);
|
||||
}
|
||||
} else {
|
||||
for (; i >= j; i--) {
|
||||
ret.push_back(i);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2006-2009 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 version 2, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* 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 license mentioned above concerns the source code only. Using the
|
||||
* EtherCAT technology and brand is only permitted in compliance with the
|
||||
* industrial property and similar rights of Beckhoff Automation GmbH.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include <list>
|
||||
using namespace std;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
class NumberListParser
|
||||
{
|
||||
public:
|
||||
NumberListParser();
|
||||
~NumberListParser();
|
||||
|
||||
typedef list<unsigned int> NumberList;
|
||||
|
||||
NumberList parse(const char *);
|
||||
|
||||
virtual unsigned int getMax() = 0;
|
||||
|
||||
private:
|
||||
unsigned int max;
|
||||
bool hasMax;
|
||||
|
||||
unsigned int maximum();
|
||||
|
||||
static bool isNumeric(char);
|
||||
static unsigned int parseNumber(const char *, unsigned int *,
|
||||
unsigned int);
|
||||
static NumberList range(unsigned int, unsigned int);
|
||||
};
|
||||
|
||||
/****************************************************************************/
|
||||
|
|
@ -61,19 +61,21 @@ using namespace std;
|
|||
#include "CommandVersion.h"
|
||||
#include "CommandXml.h"
|
||||
|
||||
#include "NumberListParser.h"
|
||||
#include "MasterDevice.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef list<Command *> CommandList;
|
||||
CommandList commandList;
|
||||
|
||||
MasterDevice masterDev;
|
||||
|
||||
string binaryBaseName;
|
||||
string commandName;
|
||||
Command::StringVector commandArgs;
|
||||
|
||||
// option variables
|
||||
unsigned int masterIndex = 0;
|
||||
list<unsigned int> masterIndices;
|
||||
string masterIndexList = "-"; // all masters
|
||||
int slavePosition = -1;
|
||||
int slaveAlias = -1;
|
||||
int domainIndex = -1;
|
||||
|
|
@ -128,6 +130,20 @@ string usage()
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
class MasterIndexParser:
|
||||
public NumberListParser
|
||||
{
|
||||
unsigned int getMax()
|
||||
{
|
||||
MasterDevice dev;
|
||||
dev.setIndex(0U);
|
||||
dev.open(MasterDevice::Read);
|
||||
return dev.getMasterCount() - 1;
|
||||
};
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void getOptions(int argc, char **argv)
|
||||
{
|
||||
int c, argCount;
|
||||
|
|
@ -153,16 +169,7 @@ void getOptions(int argc, char **argv)
|
|||
|
||||
switch (c) {
|
||||
case 'm':
|
||||
str.clear();
|
||||
str.str("");
|
||||
str << optarg;
|
||||
str >> resetiosflags(ios::basefield) // guess base from prefix
|
||||
>> masterIndex;
|
||||
if (str.fail() || masterIndex < 0) {
|
||||
cerr << "Invalid master number " << optarg << "!" << endl
|
||||
<< endl << usage();
|
||||
exit(1);
|
||||
}
|
||||
masterIndexList = optarg;
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
|
|
@ -252,6 +259,19 @@ void getOptions(int argc, char **argv)
|
|||
}
|
||||
}
|
||||
|
||||
try {
|
||||
MasterIndexParser p;
|
||||
masterIndices = p.parse(masterIndexList.c_str());
|
||||
} catch (MasterDeviceException &e) {
|
||||
cerr << "Failed to obtain number of masters: " << e.what() << endl;
|
||||
exit(1);
|
||||
} catch (runtime_error &e) {
|
||||
cerr << "Invalid master argument " << masterIndexList
|
||||
<< ": " << e.what() << endl
|
||||
<< endl << usage();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
commandName = argv[optind];
|
||||
while (++optind < argc)
|
||||
commandArgs.push_back(string(argv[optind]));
|
||||
|
|
@ -323,13 +343,19 @@ int main(int argc, char **argv)
|
|||
getOptions(argc, argv);
|
||||
|
||||
matchingCommands = getMatchingCommands(commandName);
|
||||
masterDev.setIndex(masterIndex);
|
||||
|
||||
if (masterIndices.empty()) {
|
||||
cerr << "List of master indices may not be empty!" << endl
|
||||
<< endl << usage();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (matchingCommands.size()) {
|
||||
if (matchingCommands.size() == 1) {
|
||||
cmd = matchingCommands.front();
|
||||
if (!helpRequested) {
|
||||
try {
|
||||
cmd->setMasterIndices(masterIndices);
|
||||
cmd->setVerbosity(verbosity);
|
||||
cmd->setAlias(slaveAlias);
|
||||
cmd->setPosition(slavePosition);
|
||||
|
|
@ -337,7 +363,7 @@ int main(int argc, char **argv)
|
|||
cmd->setDataType(dataTypeStr);
|
||||
cmd->setOutputFile(outputFile);
|
||||
cmd->setForce(force);
|
||||
cmd->execute(masterDev, commandArgs);
|
||||
cmd->execute(commandArgs);
|
||||
} catch (InvalidUsageException &e) {
|
||||
cerr << e.what() << endl << endl;
|
||||
cerr << binaryBaseName << " " << cmd->helpString();
|
||||
|
|
|
|||
Loading…
Reference in New Issue