Integrate skeleton of allow_overlapping_pdos from af21f0bdc7c9

Overlapping PDO API added, but not active/working.
No more changes than required to build.
EC_IOCTL_VERSION_MAGIC now 30
This commit is contained in:
Dave Page 2015-03-26 15:16:21 -04:00
parent f9dfaf3f9b
commit b8c5ff836d
6 changed files with 126 additions and 2 deletions

View File

@ -1145,6 +1145,17 @@ void ecrt_slave_config_watchdog(
*/
);
/** Configure whether a slave allows overlapping PDOs.
*
* Overlapping PDOs allows inputs to use the same space as outputs on the frame.
* This reduces the frame length.
*/
void ecrt_slave_config_overlapping_pdos(
ec_slave_config_t *sc, /**< Slave configuration. */
uint8_t allow_overlapping_pdos /**< Allow overlapping PDOs */
);
/** Add a PDO to a sync manager's PDO assignment.
*
* This method has to be called in non-realtime context before

View File

@ -120,6 +120,23 @@ void ecrt_slave_config_watchdog(ec_slave_config_t *sc,
/*****************************************************************************/
void ecrt_slave_config_overlapping_pdos(ec_slave_config_t *sc,
uint8_t allow_overlapping_pdos)
{
ec_ioctl_config_t data;
memset(&data, 0, sizeof(ec_ioctl_config_t));
data.config_index = sc->index;
data.allow_overlapping_pdos = allow_overlapping_pdos;
if (ioctl(sc->master->fd, EC_IOCTL_SC_OVERLAPPING_IO, &data) == -1) {
fprintf(stderr, "Failed to config overlapping PDOs: %s\n",
strerror(errno));
}
}
/*****************************************************************************/
int ecrt_slave_config_pdo_assign_add(ec_slave_config_t *sc,
uint8_t sync_index, uint16_t pdo_index)
{

View File

@ -2254,6 +2254,48 @@ out_return:
/*****************************************************************************/
/** Configure wether a slave allows overlapping PDOs.
*/
static ATTRIBUTES int ec_ioctl_sc_allow_overlapping_pdos(
ec_master_t *master, /**< EtherCAT master. */
void *arg, /**< ioctl() argument. */
ec_ioctl_context_t *ctx /**< Private data structure of file handle. */
)
{
ec_ioctl_config_t data;
ec_slave_config_t *sc;
int ret = 0;
if (unlikely(!ctx->requested)) {
ret = -EPERM;
goto out_return;
}
if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
ret = -EFAULT;
goto out_return;
}
if (down_interruptible(&master->master_sem)) {
ret = -EINTR;
goto out_return;
}
if (!(sc = ec_master_get_config(master, data.config_index))) {
ret = -ENOENT;
goto out_up;
}
ecrt_slave_config_overlapping_pdos(sc,
data.allow_overlapping_pdos);
out_up:
up(&master->master_sem);
out_return:
return ret;
}
/*****************************************************************************/
/** Add a PDO to the assignment.
*
* \return Zero on success, otherwise a negative error code.
@ -4447,6 +4489,13 @@ long EC_IOCTL(
}
ret = ec_ioctl_sc_watchdog(master, arg, ctx);
break;
case EC_IOCTL_SC_OVERLAPPING_IO:
if (!ctx->writable) {
ret = -EPERM;
break;
}
ret = ec_ioctl_sc_allow_overlapping_pdos(master, arg, ctx);
break;
case EC_IOCTL_SC_ADD_PDO:
if (!ctx->writable) {
ret = -EPERM;

View File

@ -56,7 +56,7 @@
*
* Increment this when changing the ioctl interface!
*/
#define EC_IOCTL_VERSION_MAGIC 29
#define EC_IOCTL_VERSION_MAGIC 30
// Command-line tool
#define EC_IOCTL_MODULE EC_IOR(0x00, ec_ioctl_module_t)
@ -153,6 +153,7 @@
#define EC_IOCTL_VOE_EXEC EC_IOWR(0x57, ec_ioctl_voe_t)
#define EC_IOCTL_VOE_DATA EC_IOWR(0x58, ec_ioctl_voe_t)
#define EC_IOCTL_SET_SEND_INTERVAL EC_IOW(0x59, size_t)
#define EC_IOCTL_SC_OVERLAPPING_IO EC_IOW(0x5a, ec_ioctl_config_t)
/*****************************************************************************/
@ -495,6 +496,7 @@ typedef struct {
int32_t slave_position;
uint16_t dc_assign_activate;
ec_sync_signal_t dc_sync[EC_SYNC_SIGNAL_COUNT];
uint8_t allow_overlapping_pdos;
} ec_ioctl_config_t;
/*****************************************************************************/

View File

@ -70,6 +70,7 @@ void ec_slave_config_init(
sc->vendor_id = vendor_id;
sc->product_code = product_code;
sc->watchdog_divider = 0; // use default
sc->allow_overlapping_pdos = 0; // default not allowed
sc->watchdog_intervals = 0; // use default
sc->slave = NULL;
@ -189,10 +190,41 @@ int ec_slave_config_prepare_fmmu(
return -EOVERFLOW;
}
fmmu = &sc->fmmu_configs[sc->used_fmmus++];
fmmu = &sc->fmmu_configs[sc->used_fmmus];
down(&sc->master->master_sem);
ec_fmmu_config_init(fmmu, sc, domain, sync_index, dir);
#if 0 //TODO overlapping PDOs
// Overlapping PDO Support from 4751747d4e6d
// FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME
// parent code does not call ec_fmmu_config_domain
// FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME
fmmu_logical_start_address = domain->tx_size;
tx_size = fmmu->data_size;
// FIXME is it enough to take only the *previous* FMMU into account?
// FIXME Need to qualify allow_overlapping_pdos with slave->sii.general_flags.enable_not_lrw
if (sc->allow_overlapping_pdos && sc->used_fmmus > 0) {
prev_fmmu = &sc->fmmu_configs[sc->used_fmmus - 1];
if (fmmu->dir != prev_fmmu->dir && prev_fmmu->tx_size != 0) {
// prev fmmu has opposite direction
// and is not already paired with prev-prev fmmu
old_prev_tx_size = prev_fmmu->tx_size;
prev_fmmu->tx_size = max(fmmu->data_size, prev_fmmu->data_size);
domain->tx_size += prev_fmmu->tx_size - old_prev_tx_size;
tx_size = 0;
fmmu_logical_start_address = prev_fmmu->logical_start_address;
}
}
ec_fmmu_config_domain(fmmu, domain, fmmu_logical_start_address, tx_size);
// Overlapping PDO Support from 4751747d4e6d
#endif
sc->used_fmmus++;
up(&sc->master->master_sem);
return fmmu->logical_start_address;
@ -560,6 +592,17 @@ void ecrt_slave_config_watchdog(ec_slave_config_t *sc,
/*****************************************************************************/
void ecrt_slave_config_overlapping_pdos(ec_slave_config_t *sc,
uint8_t allow_overlapping_pdos )
{
EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, allow_overlapping_pdos = %u)\n",
__func__, sc, allow_overlapping_pdos);
sc->allow_overlapping_pdos = allow_overlapping_pdos;
}
/*****************************************************************************/
int ecrt_slave_config_pdo_assign_add(ec_slave_config_t *sc,
uint8_t sync_index, uint16_t pdo_index)
{

View File

@ -130,6 +130,8 @@ struct ec_slave_config {
uint16_t watchdog_intervals; /**< Process data watchdog intervals (see
spec. reg. 0x0420). */
uint8_t allow_overlapping_pdos; /**< Allow input PDOs use the same frame space
as output PDOs. */
ec_slave_t *slave; /**< Slave pointer. This is \a NULL, if the slave is
offline. */