Bus configuration via 'ethercat config'.
This commit is contained in:
parent
bc3c6f320a
commit
1132577dd9
4
TODO
4
TODO
|
|
@ -8,8 +8,6 @@ $Id$
|
|||
|
||||
Version 1.4.0:
|
||||
|
||||
* Replace all Sysfs files via the new ethercat tool.
|
||||
- Config info (alias, position, type, Pdos, Sdos)
|
||||
* Slaves as array.
|
||||
* Remove the end state of the master state machine.
|
||||
* Supply new ec_master_state_t.
|
||||
|
|
@ -25,6 +23,8 @@ Version 1.4.0:
|
|||
* Attach Pdo names from SII or Coe dictioary to Pdos read via CoE.
|
||||
* Make scanning and configuration run parallel (each).
|
||||
* List of commands that require a slave.
|
||||
* Remove configs_attached flag.
|
||||
* Remove EC_IOCTL_DOMAIN_COUNT.
|
||||
|
||||
Future issues:
|
||||
|
||||
|
|
|
|||
202
master/cdev.c
202
master/cdev.c
|
|
@ -148,6 +148,7 @@ long eccdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|||
ec_ioctl_master_t data;
|
||||
|
||||
data.slave_count = master->slave_count;
|
||||
data.config_count = ec_master_config_count(master);
|
||||
data.mode = (uint8_t) master->mode;
|
||||
|
||||
memcpy(data.devices[0].address, master->main_mac, ETH_ALEN);
|
||||
|
|
@ -210,8 +211,8 @@ long eccdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|||
|
||||
if (slave->sii.name) {
|
||||
strncpy(data.name, slave->sii.name,
|
||||
EC_IOCTL_SLAVE_NAME_SIZE);
|
||||
data.name[EC_IOCTL_SLAVE_NAME_SIZE - 1] = 0;
|
||||
EC_IOCTL_STRING_SIZE);
|
||||
data.name[EC_IOCTL_STRING_SIZE - 1] = 0;
|
||||
} else {
|
||||
data.name[0] = 0;
|
||||
}
|
||||
|
|
@ -306,8 +307,8 @@ long eccdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|||
data.entry_count = ec_pdo_entry_count(pdo);
|
||||
|
||||
if (pdo->name) {
|
||||
strncpy(data.name, pdo->name, EC_IOCTL_PDO_NAME_SIZE);
|
||||
data.name[EC_IOCTL_PDO_NAME_SIZE - 1] = 0;
|
||||
strncpy(data.name, pdo->name, EC_IOCTL_STRING_SIZE);
|
||||
data.name[EC_IOCTL_STRING_SIZE - 1] = 0;
|
||||
} else {
|
||||
data.name[0] = 0;
|
||||
}
|
||||
|
|
@ -369,9 +370,8 @@ long eccdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|||
data.subindex = entry->subindex;
|
||||
data.bit_length = entry->bit_length;
|
||||
if (entry->name) {
|
||||
strncpy(data.name, entry->name,
|
||||
EC_IOCTL_PDO_ENTRY_NAME_SIZE);
|
||||
data.name[EC_IOCTL_PDO_ENTRY_NAME_SIZE - 1] = 0;
|
||||
strncpy(data.name, entry->name, EC_IOCTL_STRING_SIZE);
|
||||
data.name[EC_IOCTL_STRING_SIZE - 1] = 0;
|
||||
} else {
|
||||
data.name[0] = 0;
|
||||
}
|
||||
|
|
@ -546,8 +546,8 @@ long eccdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|||
data.max_subindex = sdo->max_subindex;
|
||||
|
||||
if (sdo->name) {
|
||||
strncpy(data.name, sdo->name, EC_IOCTL_SDO_NAME_SIZE);
|
||||
data.name[EC_IOCTL_SDO_NAME_SIZE - 1] = 0;
|
||||
strncpy(data.name, sdo->name, EC_IOCTL_STRING_SIZE);
|
||||
data.name[EC_IOCTL_STRING_SIZE - 1] = 0;
|
||||
} else {
|
||||
data.name[0] = 0;
|
||||
}
|
||||
|
|
@ -610,8 +610,8 @@ long eccdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|||
|
||||
if (entry->description) {
|
||||
strncpy(data.description, entry->description,
|
||||
EC_IOCTL_SDO_ENTRY_DESCRIPTION_SIZE);
|
||||
data.description[EC_IOCTL_SDO_ENTRY_DESCRIPTION_SIZE - 1]
|
||||
EC_IOCTL_STRING_SIZE);
|
||||
data.description[EC_IOCTL_STRING_SIZE - 1]
|
||||
= 0;
|
||||
} else {
|
||||
data.description[0] = 0;
|
||||
|
|
@ -853,6 +853,186 @@ long eccdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|||
break;
|
||||
}
|
||||
|
||||
case EC_IOCTL_CONFIG:
|
||||
{
|
||||
ec_ioctl_config_t data;
|
||||
const ec_slave_config_t *sc;
|
||||
|
||||
if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
|
||||
retval = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(sc = ec_master_get_config_const(
|
||||
master, data.config_index))) {
|
||||
EC_ERR("Slave config %u does not exist!\n",
|
||||
data.config_index);
|
||||
retval = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
data.alias = sc->alias;
|
||||
data.position = sc->position;
|
||||
data.vendor_id = sc->vendor_id;
|
||||
data.product_code = sc->product_code;
|
||||
data.pdo_count[EC_DIR_OUTPUT] =
|
||||
ec_pdo_list_count(&sc->pdos[EC_DIR_OUTPUT]);
|
||||
data.pdo_count[EC_DIR_INPUT] =
|
||||
ec_pdo_list_count(&sc->pdos[EC_DIR_INPUT]);
|
||||
data.sdo_count = ec_slave_config_sdo_count(sc);
|
||||
data.attached = sc->slave != NULL;
|
||||
|
||||
if (copy_to_user((void __user *) arg, &data, sizeof(data))) {
|
||||
retval = -EFAULT;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case EC_IOCTL_CONFIG_PDO:
|
||||
{
|
||||
ec_ioctl_config_pdo_t data;
|
||||
const ec_slave_config_t *sc;
|
||||
const ec_pdo_t *pdo;
|
||||
|
||||
if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
|
||||
retval = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(sc = ec_master_get_config_const(
|
||||
master, data.config_index))) {
|
||||
EC_ERR("Slave config %u does not exist!\n",
|
||||
data.config_index);
|
||||
retval = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (data.direction > EC_DIR_INPUT) {
|
||||
EC_ERR("Invalid direction %u!\n", data.direction);
|
||||
retval = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(pdo = ec_pdo_list_find_pdo_by_pos_const(
|
||||
&sc->pdos[data.direction], data.pdo_pos))) {
|
||||
EC_ERR("Invalid Pdo position!\n");
|
||||
retval = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
data.index = pdo->index;
|
||||
data.entry_count = ec_pdo_entry_count(pdo);
|
||||
|
||||
if (pdo->name) {
|
||||
strncpy(data.name, pdo->name, EC_IOCTL_STRING_SIZE);
|
||||
data.name[EC_IOCTL_STRING_SIZE - 1] = 0;
|
||||
} else {
|
||||
data.name[0] = 0;
|
||||
}
|
||||
|
||||
if (copy_to_user((void __user *) arg, &data, sizeof(data))) {
|
||||
retval = -EFAULT;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case EC_IOCTL_CONFIG_PDO_ENTRY:
|
||||
{
|
||||
ec_ioctl_config_pdo_entry_t data;
|
||||
const ec_slave_config_t *sc;
|
||||
const ec_pdo_t *pdo;
|
||||
const ec_pdo_entry_t *entry;
|
||||
|
||||
if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
|
||||
retval = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(sc = ec_master_get_config_const(
|
||||
master, data.config_index))) {
|
||||
EC_ERR("Slave config %u does not exist!\n",
|
||||
data.config_index);
|
||||
retval = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (data.direction > EC_DIR_INPUT) {
|
||||
EC_ERR("Invalid direction %u!\n", data.direction);
|
||||
retval = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(pdo = ec_pdo_list_find_pdo_by_pos_const(
|
||||
&sc->pdos[data.direction], data.pdo_pos))) {
|
||||
EC_ERR("Invalid Pdo position!\n");
|
||||
retval = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(entry = ec_pdo_find_entry_by_pos_const(
|
||||
pdo, data.entry_pos))) {
|
||||
EC_ERR("Entry not found!\n");
|
||||
retval = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
data.index = entry->index;
|
||||
data.subindex = entry->subindex;
|
||||
data.bit_length = entry->bit_length;
|
||||
if (entry->name) {
|
||||
strncpy(data.name, entry->name, EC_IOCTL_STRING_SIZE);
|
||||
data.name[EC_IOCTL_STRING_SIZE - 1] = 0;
|
||||
} else {
|
||||
data.name[0] = 0;
|
||||
}
|
||||
|
||||
if (copy_to_user((void __user *) arg, &data, sizeof(data))) {
|
||||
retval = -EFAULT;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case EC_IOCTL_CONFIG_SDO:
|
||||
{
|
||||
ec_ioctl_config_sdo_t data;
|
||||
const ec_slave_config_t *sc;
|
||||
const ec_sdo_request_t *req;
|
||||
|
||||
if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
|
||||
retval = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(sc = ec_master_get_config_const(
|
||||
master, data.config_index))) {
|
||||
EC_ERR("Slave config %u does not exist!\n",
|
||||
data.config_index);
|
||||
retval = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(req = ec_slave_config_get_sdo_by_pos_const(
|
||||
sc, data.sdo_pos))) {
|
||||
EC_ERR("Invalid Sdo position!\n");
|
||||
retval = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
data.index = req->index;
|
||||
data.subindex = req->subindex;
|
||||
data.size = req->data_size;
|
||||
memcpy(&data.data, req->data, min((u32) data.size, (u32) 4));
|
||||
|
||||
if (copy_to_user((void __user *) arg, &data, sizeof(data))) {
|
||||
retval = -EFAULT;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
retval = -ENOTTY;
|
||||
}
|
||||
|
|
|
|||
123
master/ioctl.h
123
master/ioctl.h
|
|
@ -54,28 +54,35 @@
|
|||
#define EC_IOW(nr,type) _IOW(EC_IOCTL_TYPE,nr,type)
|
||||
#define EC_IOWR(nr,type) _IOWR(EC_IOCTL_TYPE,nr,type)
|
||||
|
||||
#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_SYNC EC_IOWR(0x02, ec_ioctl_sync_t)
|
||||
#define EC_IOCTL_PDO EC_IOWR(0x03, ec_ioctl_pdo_t)
|
||||
#define EC_IOCTL_PDO_ENTRY EC_IOWR(0x04, ec_ioctl_pdo_entry_t)
|
||||
#define EC_IOCTL_DOMAIN_COUNT EC_IO(0x05)
|
||||
#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_DATA EC_IOWR(0x08, ec_ioctl_data_t)
|
||||
#define EC_IOCTL_SET_DEBUG EC_IO(0x09)
|
||||
#define EC_IOCTL_SLAVE_STATE EC_IOW(0x0a, ec_ioctl_slave_state_t)
|
||||
#define EC_IOCTL_SDO EC_IOWR(0x0b, ec_ioctl_sdo_t)
|
||||
#define EC_IOCTL_SDO_ENTRY EC_IOWR(0x0c, ec_ioctl_sdo_entry_t)
|
||||
#define EC_IOCTL_SDO_UPLOAD EC_IOWR(0x0d, ec_ioctl_sdo_upload_t)
|
||||
#define EC_IOCTL_SDO_DOWNLOAD EC_IOW(0x0e, ec_ioctl_sdo_download_t)
|
||||
#define EC_IOCTL_SII_READ EC_IOWR(0x0f, ec_ioctl_sii_t)
|
||||
#define EC_IOCTL_SII_WRITE EC_IOW(0x10, ec_ioctl_sii_t)
|
||||
#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_SYNC EC_IOWR(0x02, ec_ioctl_sync_t)
|
||||
#define EC_IOCTL_PDO EC_IOWR(0x03, ec_ioctl_pdo_t)
|
||||
#define EC_IOCTL_PDO_ENTRY EC_IOWR(0x04, ec_ioctl_pdo_entry_t)
|
||||
#define EC_IOCTL_DOMAIN_COUNT EC_IO(0x05)
|
||||
#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_DATA EC_IOWR(0x08, ec_ioctl_data_t)
|
||||
#define EC_IOCTL_SET_DEBUG EC_IO(0x09)
|
||||
#define EC_IOCTL_SLAVE_STATE EC_IOW(0x0a, ec_ioctl_slave_state_t)
|
||||
#define EC_IOCTL_SDO EC_IOWR(0x0b, ec_ioctl_sdo_t)
|
||||
#define EC_IOCTL_SDO_ENTRY EC_IOWR(0x0c, ec_ioctl_sdo_entry_t)
|
||||
#define EC_IOCTL_SDO_UPLOAD EC_IOWR(0x0d, ec_ioctl_sdo_upload_t)
|
||||
#define EC_IOCTL_SDO_DOWNLOAD EC_IOW(0x0e, ec_ioctl_sdo_download_t)
|
||||
#define EC_IOCTL_SII_READ EC_IOWR(0x0f, ec_ioctl_sii_t)
|
||||
#define EC_IOCTL_SII_WRITE EC_IOW(0x10, ec_ioctl_sii_t)
|
||||
#define EC_IOCTL_CONFIG EC_IOWR(0x11, ec_ioctl_config_t)
|
||||
#define EC_IOCTL_CONFIG_PDO EC_IOWR(0x12, ec_ioctl_config_pdo_t)
|
||||
#define EC_IOCTL_CONFIG_PDO_ENTRY EC_IOWR(0x12, ec_ioctl_config_pdo_entry_t)
|
||||
#define EC_IOCTL_CONFIG_SDO EC_IOWR(0x13, ec_ioctl_config_sdo_t)
|
||||
|
||||
#define EC_IOCTL_STRING_SIZE 64
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
uint32_t slave_count;
|
||||
uint32_t config_count;
|
||||
uint8_t mode;
|
||||
struct {
|
||||
uint8_t address[6];
|
||||
|
|
@ -87,8 +94,6 @@ typedef struct {
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define EC_IOCTL_SLAVE_NAME_SIZE 77
|
||||
|
||||
typedef struct {
|
||||
// input
|
||||
uint16_t position;
|
||||
|
|
@ -113,7 +118,7 @@ typedef struct {
|
|||
uint8_t sync_count;
|
||||
uint16_t sdo_count;
|
||||
uint32_t sii_nwords;
|
||||
char name[EC_IOCTL_SLAVE_NAME_SIZE];
|
||||
char name[EC_IOCTL_STRING_SIZE];
|
||||
} ec_ioctl_slave_t;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -134,8 +139,6 @@ typedef struct {
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define EC_IOCTL_PDO_NAME_SIZE 114
|
||||
|
||||
typedef struct {
|
||||
// inputs
|
||||
uint16_t slave_position;
|
||||
|
|
@ -146,13 +149,11 @@ typedef struct {
|
|||
uint8_t dir;
|
||||
uint16_t index;
|
||||
uint8_t entry_count;
|
||||
char name[EC_IOCTL_PDO_NAME_SIZE];
|
||||
int8_t name[EC_IOCTL_STRING_SIZE];
|
||||
} ec_ioctl_pdo_t;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define EC_IOCTL_PDO_ENTRY_NAME_SIZE 110
|
||||
|
||||
typedef struct {
|
||||
// inputs
|
||||
uint16_t slave_position;
|
||||
|
|
@ -164,7 +165,7 @@ typedef struct {
|
|||
uint16_t index;
|
||||
uint8_t subindex;
|
||||
uint8_t bit_length;
|
||||
char name[EC_IOCTL_PDO_NAME_SIZE];
|
||||
int8_t name[EC_IOCTL_STRING_SIZE];
|
||||
} ec_ioctl_pdo_entry_t;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -202,7 +203,7 @@ typedef struct {
|
|||
// inputs
|
||||
uint32_t domain_index;
|
||||
uint32_t data_size;
|
||||
unsigned char *target;
|
||||
uint8_t *target;
|
||||
} ec_ioctl_data_t;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -215,8 +216,6 @@ typedef struct {
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define EC_IOCTL_SDO_NAME_SIZE 121
|
||||
|
||||
typedef struct {
|
||||
// inputs
|
||||
uint16_t slave_position;
|
||||
|
|
@ -225,13 +224,11 @@ typedef struct {
|
|||
// outputs
|
||||
uint16_t sdo_index;
|
||||
uint8_t max_subindex;
|
||||
char name[EC_IOCTL_SDO_NAME_SIZE];
|
||||
int8_t name[EC_IOCTL_STRING_SIZE];
|
||||
} ec_ioctl_sdo_t;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define EC_IOCTL_SDO_ENTRY_DESCRIPTION_SIZE 120
|
||||
|
||||
typedef struct {
|
||||
// inputs
|
||||
uint16_t slave_position;
|
||||
|
|
@ -241,7 +238,7 @@ typedef struct {
|
|||
// outputs
|
||||
uint16_t data_type;
|
||||
uint16_t bit_length;
|
||||
char description[EC_IOCTL_SDO_ENTRY_DESCRIPTION_SIZE];
|
||||
int8_t description[EC_IOCTL_STRING_SIZE];
|
||||
} ec_ioctl_sdo_entry_t;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -281,4 +278,64 @@ typedef struct {
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
// inputs
|
||||
uint32_t config_index;
|
||||
|
||||
// outputs
|
||||
uint16_t alias;
|
||||
uint16_t position;
|
||||
uint32_t vendor_id;
|
||||
uint32_t product_code;
|
||||
uint32_t pdo_count[2];
|
||||
uint32_t sdo_count;
|
||||
uint8_t attached;
|
||||
} ec_ioctl_config_t;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
// inputs
|
||||
uint32_t config_index;
|
||||
uint32_t direction;
|
||||
uint32_t pdo_pos;
|
||||
|
||||
// outputs
|
||||
uint16_t index;
|
||||
uint8_t entry_count;
|
||||
int8_t name[EC_IOCTL_STRING_SIZE];
|
||||
} ec_ioctl_config_pdo_t;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
// inputs
|
||||
uint32_t config_index;
|
||||
uint32_t direction;
|
||||
uint32_t pdo_pos;
|
||||
uint32_t entry_pos;
|
||||
|
||||
// outputs
|
||||
uint16_t index;
|
||||
uint8_t subindex;
|
||||
uint8_t bit_length;
|
||||
int8_t name[EC_IOCTL_STRING_SIZE];
|
||||
} ec_ioctl_config_pdo_entry_t;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
// inputs
|
||||
uint32_t config_index;
|
||||
uint32_t sdo_pos;
|
||||
|
||||
// outputs
|
||||
uint16_t index;
|
||||
uint8_t subindex;
|
||||
uint32_t size;
|
||||
uint8_t data[4];
|
||||
} ec_ioctl_config_sdo_t;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1101,6 +1101,40 @@ ec_slave_t *ec_master_find_slave(
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
unsigned int ec_master_config_count(
|
||||
const ec_master_t *master /**< EtherCAT master. */
|
||||
)
|
||||
{
|
||||
const ec_slave_config_t *sc;
|
||||
unsigned int count = 0;
|
||||
|
||||
list_for_each_entry(sc, &master->configs, list) {
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
const ec_slave_config_t *ec_master_get_config_const(
|
||||
const ec_master_t *master, /**< EtherCAT master. */
|
||||
unsigned int index /**< List position. */
|
||||
)
|
||||
{
|
||||
const ec_slave_config_t *sc;
|
||||
|
||||
list_for_each_entry(sc, &master->configs, list) {
|
||||
if (index--)
|
||||
continue;
|
||||
return sc;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
unsigned int ec_master_domain_count(
|
||||
const ec_master_t *master /**< EtherCAT master. */
|
||||
)
|
||||
|
|
|
|||
|
|
@ -197,6 +197,9 @@ void ec_master_clear_eoe_handlers(ec_master_t *);
|
|||
#endif
|
||||
void ec_master_destroy_slaves(ec_master_t *);
|
||||
|
||||
unsigned int ec_master_config_count(const ec_master_t *);
|
||||
const ec_slave_config_t *ec_master_get_config_const(
|
||||
const ec_master_t *, unsigned int);
|
||||
unsigned int ec_master_domain_count(const ec_master_t *);
|
||||
ec_domain_t *ec_master_find_domain(ec_master_t *, unsigned int);
|
||||
|
||||
|
|
|
|||
|
|
@ -462,6 +462,46 @@ void ec_slave_config_load_default_mapping(
|
|||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
*/
|
||||
unsigned int ec_slave_config_sdo_count(
|
||||
const ec_slave_config_t *sc /**< Slave configuration. */
|
||||
)
|
||||
{
|
||||
const ec_sdo_request_t *req;
|
||||
unsigned int count = 0;
|
||||
|
||||
list_for_each_entry(req, &sc->sdo_configs, list) {
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Finds an Sdo configuration via its position in the list.
|
||||
*
|
||||
* Const version.
|
||||
*/
|
||||
const ec_sdo_request_t *ec_slave_config_get_sdo_by_pos_const(
|
||||
const ec_slave_config_t *sc, /**< Slave configuration. */
|
||||
unsigned int pos /**< Position in the list. */
|
||||
)
|
||||
{
|
||||
const ec_sdo_request_t *req;
|
||||
|
||||
list_for_each_entry(req, &sc->sdo_configs, list) {
|
||||
if (pos--)
|
||||
continue;
|
||||
return req;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Realtime interface
|
||||
*****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -91,6 +91,10 @@ void ec_slave_config_load_default_assignment(ec_slave_config_t *);
|
|||
void ec_slave_config_load_default_mapping(const ec_slave_config_t *,
|
||||
ec_pdo_t *);
|
||||
|
||||
unsigned int ec_slave_config_sdo_count(const ec_slave_config_t *);
|
||||
const ec_sdo_request_t *ec_slave_config_get_sdo_by_pos_const(
|
||||
const ec_slave_config_t *, unsigned int);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#endif
|
||||
|
|
|
|||
166
tools/Master.cpp
166
tools/Master.cpp
|
|
@ -171,6 +171,94 @@ void Master::writeAlias(
|
|||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Lists the bus configuration.
|
||||
*/
|
||||
void Master::showConfig()
|
||||
{
|
||||
ec_ioctl_master_t master;
|
||||
unsigned int i, j, k, l;
|
||||
ec_ioctl_config_t config;
|
||||
ec_ioctl_config_pdo_t pdo;
|
||||
ec_ioctl_config_pdo_entry_t entry;
|
||||
ec_ioctl_config_sdo_t sdo;
|
||||
|
||||
open(Read);
|
||||
getMaster(&master);
|
||||
|
||||
for (i = 0; i < master.config_count; i++) {
|
||||
getConfig(&config, i);
|
||||
|
||||
cout << "Alias: 0x"
|
||||
<< hex << setfill('0') << setw(4) << config.alias << endl
|
||||
<< "Position: " << dec << config.position << endl
|
||||
<< "Vendor Id: 0x"
|
||||
<< hex << setw(8) << config.vendor_id << endl
|
||||
<< "Product code: 0x"
|
||||
<< hex << setw(8) << config.product_code << endl
|
||||
<< "Attached: " << (config.attached ? "yes" : "no") << endl;
|
||||
|
||||
for (j = 0; j < 2; j++) {
|
||||
if (config.pdo_count[j]) {
|
||||
cout << (j ? "Input" : "Output")
|
||||
<< " Pdo assignment / mapping " << endl;
|
||||
for (k = 0; k < config.pdo_count[j]; k++) {
|
||||
getConfigPdo(&pdo, i, j, k);
|
||||
|
||||
cout << " Pdo 0x"
|
||||
<< hex << setfill('0') << setw(4) << pdo.index
|
||||
<< " \"" << pdo.name << "\"" << endl;
|
||||
|
||||
for (l = 0; l < pdo.entry_count; l++) {
|
||||
getConfigPdoEntry(&entry, i, j, k, l);
|
||||
|
||||
cout << " Pdo entry 0x"
|
||||
<< hex << setfill('0') << setw(4) << entry.index
|
||||
<< ":" << setw(2) << (unsigned int) entry.subindex
|
||||
<< ", " << dec << (unsigned int) entry.bit_length
|
||||
<< " bit, \"" << entry.name << "\"" << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (config.sdo_count) {
|
||||
cout << "Sdo configuration:" << endl;
|
||||
for (j = 0; j < config.sdo_count; j++) {
|
||||
getConfigSdo(&sdo, i, j);
|
||||
|
||||
cout << " 0x"
|
||||
<< hex << setfill('0') << setw(4) << sdo.index
|
||||
<< ":" << setw(2) << (unsigned int) sdo.subindex
|
||||
<< ", " << sdo.size << " byte: " << hex;
|
||||
|
||||
switch (sdo.size) {
|
||||
case 1:
|
||||
cout << "0x" << setw(2)
|
||||
<< (unsigned int) *(uint8_t *) &sdo.data;
|
||||
break;
|
||||
case 2:
|
||||
cout << "0x" << setw(4)
|
||||
<< le16tocpu(*(uint16_t *) &sdo.data);
|
||||
break;
|
||||
case 4:
|
||||
cout << "0x" << setw(8)
|
||||
<< le32tocpu(*(uint32_t *) &sdo.data);
|
||||
break;
|
||||
default:
|
||||
cout << "???";
|
||||
}
|
||||
|
||||
cout << endl;
|
||||
}
|
||||
}
|
||||
|
||||
cout << endl;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
void Master::outputData(int domainIndex)
|
||||
|
|
@ -1156,8 +1244,7 @@ void Master::listSlavePdos(
|
|||
|
||||
cout << " Pdo entry 0x"
|
||||
<< hex << setfill('0') << setw(4) << entry.index
|
||||
<< ":" << hex << setfill('0') << setw(2)
|
||||
<< (unsigned int) entry.subindex
|
||||
<< ":" << setw(2) << (unsigned int) entry.subindex
|
||||
<< ", " << dec << (unsigned int) entry.bit_length
|
||||
<< " bit, \"" << entry.name << "\"" << endl;
|
||||
}
|
||||
|
|
@ -1306,7 +1393,7 @@ void Master::showSlave(uint16_t slavePosition)
|
|||
<< " Enable notLRW: "
|
||||
<< (slave.general_flags.enable_not_lrw ? "yes" : "no") << endl
|
||||
<< " Current consumption: "
|
||||
<< dec << slave.current_on_ebus << " mA" << endl << sizeof(slave);
|
||||
<< dec << slave.current_on_ebus << " mA" << endl;
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
|
@ -1447,6 +1534,79 @@ void Master::getMaster(ec_ioctl_master_t *data)
|
|||
|
||||
/****************************************************************************/
|
||||
|
||||
void Master::getConfig(ec_ioctl_config_t *data, unsigned int index)
|
||||
{
|
||||
data->config_index = index;
|
||||
|
||||
if (ioctl(fd, EC_IOCTL_CONFIG, data) < 0) {
|
||||
stringstream err;
|
||||
err << "Failed to get slave configuration: " << strerror(errno);
|
||||
throw MasterException(err.str());
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
void Master::getConfigPdo(
|
||||
ec_ioctl_config_pdo_t *data,
|
||||
unsigned int index,
|
||||
unsigned int dir,
|
||||
unsigned int pdo_pos
|
||||
)
|
||||
{
|
||||
data->config_index = index;
|
||||
data->direction = dir;
|
||||
data->pdo_pos = pdo_pos;
|
||||
|
||||
if (ioctl(fd, EC_IOCTL_CONFIG_PDO, data) < 0) {
|
||||
stringstream err;
|
||||
err << "Failed to get slave config Pdo: " << strerror(errno);
|
||||
throw MasterException(err.str());
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
void Master::getConfigPdoEntry(
|
||||
ec_ioctl_config_pdo_entry_t *data,
|
||||
unsigned int index,
|
||||
unsigned int dir,
|
||||
unsigned int pdo_pos,
|
||||
unsigned int entry_pos
|
||||
)
|
||||
{
|
||||
data->config_index = index;
|
||||
data->direction = dir;
|
||||
data->pdo_pos = pdo_pos;
|
||||
data->entry_pos = entry_pos;
|
||||
|
||||
if (ioctl(fd, EC_IOCTL_CONFIG_PDO_ENTRY, data) < 0) {
|
||||
stringstream err;
|
||||
err << "Failed to get slave config Pdo entry: " << strerror(errno);
|
||||
throw MasterException(err.str());
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
void Master::getConfigSdo(
|
||||
ec_ioctl_config_sdo_t *data,
|
||||
unsigned int index,
|
||||
unsigned int sdo_pos
|
||||
)
|
||||
{
|
||||
data->config_index = index;
|
||||
data->sdo_pos = sdo_pos;
|
||||
|
||||
if (ioctl(fd, EC_IOCTL_CONFIG_SDO, data) < 0) {
|
||||
stringstream err;
|
||||
err << "Failed to get slave config Sdo: " << strerror(errno);
|
||||
throw MasterException(err.str());
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
void Master::getDomain(ec_ioctl_domain_t *data, unsigned int index)
|
||||
{
|
||||
data->index = index;
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ class Master
|
|||
void setIndex(unsigned int);
|
||||
|
||||
void writeAlias(int, bool, const vector<string> &);
|
||||
void showConfig();
|
||||
void outputData(int);
|
||||
void setDebug(const vector<string> &);
|
||||
void showDomains(int);
|
||||
|
|
@ -72,7 +73,12 @@ class Master
|
|||
unsigned int domainCount();
|
||||
unsigned int slaveCount();
|
||||
void getMaster(ec_ioctl_master_t *);
|
||||
void slaveSyncs(uint16_t);
|
||||
void getConfig(ec_ioctl_config_t *, unsigned int);
|
||||
void getConfigPdo(ec_ioctl_config_pdo_t *, unsigned int,
|
||||
unsigned int, unsigned int);
|
||||
void getConfigPdoEntry(ec_ioctl_config_pdo_entry_t *, unsigned int,
|
||||
unsigned int, unsigned int, unsigned int);
|
||||
void getConfigSdo(ec_ioctl_config_sdo_t *, unsigned int, unsigned int);
|
||||
void getDomain(ec_ioctl_domain_t *, unsigned int);
|
||||
void getFmmu(ec_ioctl_domain_fmmu_t *, unsigned int, unsigned int);
|
||||
void getData(ec_ioctl_data_t *, unsigned int, unsigned int,
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ void printUsage()
|
|||
<< "Usage: ethercat <COMMAND> [OPTIONS]" << endl
|
||||
<< "Commands:" << endl
|
||||
<< " alias Write alias address(es)." << endl
|
||||
<< " config Show slave configurations." << endl
|
||||
<< " data Output binary domain process data." << endl
|
||||
<< " debug Set the master debug level." << endl
|
||||
<< " domain Show domain information." << endl
|
||||
|
|
@ -178,6 +179,8 @@ int main(int argc, char **argv)
|
|||
|
||||
if (command == "alias") {
|
||||
master.writeAlias(slavePosition, force, commandArgs);
|
||||
} else if (command == "config") {
|
||||
master.showConfig();
|
||||
} else if (command == "data") {
|
||||
master.outputData(domainIndex);
|
||||
} else if (command == "debug") {
|
||||
|
|
|
|||
Loading…
Reference in New Issue