# HG changeset patch # User Dave Page # Date 1427397381 14400 # Node ID 777d1a8b3a2737d8dd8b2f1421d6a386c4a0cae3 # Parent ec0b5d9a2ff145f897f39ffdc4eb3dd18fd3466a 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 diff -r ec0b5d9a2ff1 -r 777d1a8b3a27 include/ecrt.h --- a/include/ecrt.h Mon Mar 16 14:18:55 2015 -0400 +++ b/include/ecrt.h Thu Mar 26 15:16:21 2015 -0400 @@ -1145,6 +1145,17 @@ */ ); +/** 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 diff -r ec0b5d9a2ff1 -r 777d1a8b3a27 lib/slave_config.c --- a/lib/slave_config.c Mon Mar 16 14:18:55 2015 -0400 +++ b/lib/slave_config.c Thu Mar 26 15:16:21 2015 -0400 @@ -120,6 +120,23 @@ /*****************************************************************************/ +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) { diff -r ec0b5d9a2ff1 -r 777d1a8b3a27 master/ioctl.c --- a/master/ioctl.c Mon Mar 16 14:18:55 2015 -0400 +++ b/master/ioctl.c Thu Mar 26 15:16:21 2015 -0400 @@ -2254,6 +2254,48 @@ /*****************************************************************************/ +/** 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 @@ } 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; diff -r ec0b5d9a2ff1 -r 777d1a8b3a27 master/ioctl.h --- a/master/ioctl.h Mon Mar 16 14:18:55 2015 -0400 +++ b/master/ioctl.h Thu Mar 26 15:16:21 2015 -0400 @@ -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 @@ 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; /*****************************************************************************/ diff -r ec0b5d9a2ff1 -r 777d1a8b3a27 master/slave_config.c --- a/master/slave_config.c Mon Mar 16 14:18:55 2015 -0400 +++ b/master/slave_config.c Thu Mar 26 15:16:21 2015 -0400 @@ -70,6 +70,7 @@ 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 @@ 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_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) { diff -r ec0b5d9a2ff1 -r 777d1a8b3a27 master/slave_config.h --- a/master/slave_config.h Mon Mar 16 14:18:55 2015 -0400 +++ b/master/slave_config.h Thu Mar 26 15:16:21 2015 -0400 @@ -130,6 +130,8 @@ 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. */