diff --git a/include/ecrt.h b/include/ecrt.h index a284ecf5..4ab1d00b 100644 --- a/include/ecrt.h +++ b/include/ecrt.h @@ -1519,16 +1519,16 @@ int ecrt_domain_reg_pdo_entry_list( registrations. */ ); -#ifdef __KERNEL__ - /** Returns the current size of the domain's process data. * - * \return Size of the process data image. + * \return Size of the process data image, or a negative error code. */ size_t ecrt_domain_size( const ec_domain_t *domain /**< Domain. */ ); +#ifdef __KERNEL__ + /** Provide external memory to store the domain's process data. * * Call this after all PDO entries have been registered and before activating diff --git a/lib/domain.c b/lib/domain.c index 22a476c6..1ee838b8 100644 --- a/lib/domain.c +++ b/lib/domain.c @@ -76,6 +76,21 @@ int ecrt_domain_reg_pdo_entry_list(ec_domain_t *domain, /*****************************************************************************/ +size_t ecrt_domain_size(const ec_domain_t *domain) +{ + int ret; + + ret = ioctl(domain->master->fd, EC_IOCTL_DOMAIN_SIZE, domain->index); + if (EC_IOCTL_IS_ERROR(ret)) { + fprintf(stderr, "Failed to get domain size: %s\n", + strerror(EC_IOCTL_ERRNO(ret))); + } + + return ret; +} + +/*****************************************************************************/ + uint8_t *ecrt_domain_data(ec_domain_t *domain) { if (!domain->process_data) { diff --git a/master/ioctl.c b/master/ioctl.c index 0fa7522f..b03e28b1 100644 --- a/master/ioctl.c +++ b/master/ioctl.c @@ -2730,6 +2730,38 @@ static ATTRIBUTES int ec_ioctl_sc_idn( /*****************************************************************************/ +/** Gets the domain's data size. + */ +static ATTRIBUTES int ec_ioctl_domain_size( + ec_master_t *master, /**< EtherCAT master. */ + void *arg, /**< ioctl() argument. */ + ec_ioctl_context_t *ctx /**< Private data structure of file handle. */ + ) +{ + const ec_domain_t *domain; + + if (unlikely(!ctx->requested)) { + return -EPERM; + } + + if (down_interruptible(&master->master_sem)) { + return -EINTR; + } + + list_for_each_entry(domain, &master->domains, list) { + if (domain->index == (unsigned long) arg) { + size_t size = ecrt_domain_size(domain); + up(&master->master_sem); + return size; + } + } + + up(&master->master_sem); + return -ENOENT; +} + +/*****************************************************************************/ + /** Gets the domain's offset in the total process data. */ static ATTRIBUTES int ec_ioctl_domain_offset( @@ -4186,6 +4218,9 @@ long EC_IOCTL(ec_master_t *master, ec_ioctl_context_t *ctx, } ret = ec_ioctl_sc_idn(master, arg, ctx); break; + case EC_IOCTL_DOMAIN_SIZE: + ret = ec_ioctl_domain_size(master, arg, ctx); + break; case EC_IOCTL_DOMAIN_OFFSET: ret = ec_ioctl_domain_offset(master, arg, ctx); break; diff --git a/master/ioctl.h b/master/ioctl.h index 4b5b69bd..d06fd28d 100644 --- a/master/ioctl.h +++ b/master/ioctl.h @@ -56,7 +56,7 @@ * * Increment this when changing the ioctl interface! */ -#define EC_IOCTL_VERSION_MAGIC 25 +#define EC_IOCTL_VERSION_MAGIC 26 // Command-line tool #define EC_IOCTL_MODULE EC_IOR(0x00, ec_ioctl_module_t) @@ -128,28 +128,29 @@ #define EC_IOCTL_SC_VOE EC_IOWR(0x3e, ec_ioctl_voe_t) #define EC_IOCTL_SC_STATE EC_IOWR(0x3f, ec_ioctl_sc_state_t) #define EC_IOCTL_SC_IDN EC_IOW(0x40, ec_ioctl_sc_idn_t) -#define EC_IOCTL_DOMAIN_OFFSET EC_IO(0x41) -#define EC_IOCTL_DOMAIN_PROCESS EC_IO(0x42) -#define EC_IOCTL_DOMAIN_QUEUE EC_IO(0x43) -#define EC_IOCTL_DOMAIN_STATE EC_IOWR(0x44, ec_ioctl_domain_state_t) -#define EC_IOCTL_SDO_REQUEST_INDEX EC_IOWR(0x45, ec_ioctl_sdo_request_t) -#define EC_IOCTL_SDO_REQUEST_TIMEOUT EC_IOWR(0x46, ec_ioctl_sdo_request_t) -#define EC_IOCTL_SDO_REQUEST_STATE EC_IOWR(0x47, ec_ioctl_sdo_request_t) -#define EC_IOCTL_SDO_REQUEST_READ EC_IOWR(0x48, ec_ioctl_sdo_request_t) -#define EC_IOCTL_SDO_REQUEST_WRITE EC_IOWR(0x49, ec_ioctl_sdo_request_t) -#define EC_IOCTL_SDO_REQUEST_DATA EC_IOWR(0x4a, ec_ioctl_sdo_request_t) -#define EC_IOCTL_REG_REQUEST_DATA EC_IOWR(0x4b, ec_ioctl_reg_request_t) -#define EC_IOCTL_REG_REQUEST_STATE EC_IOWR(0x4c, ec_ioctl_reg_request_t) -#define EC_IOCTL_REG_REQUEST_WRITE EC_IOWR(0x4d, ec_ioctl_reg_request_t) -#define EC_IOCTL_REG_REQUEST_READ EC_IOWR(0x4e, ec_ioctl_reg_request_t) -#define EC_IOCTL_VOE_SEND_HEADER EC_IOW(0x4f, ec_ioctl_voe_t) -#define EC_IOCTL_VOE_REC_HEADER EC_IOWR(0x50, ec_ioctl_voe_t) -#define EC_IOCTL_VOE_READ EC_IOW(0x51, ec_ioctl_voe_t) -#define EC_IOCTL_VOE_READ_NOSYNC EC_IOW(0x52, ec_ioctl_voe_t) -#define EC_IOCTL_VOE_WRITE EC_IOWR(0x53, ec_ioctl_voe_t) -#define EC_IOCTL_VOE_EXEC EC_IOWR(0x54, ec_ioctl_voe_t) -#define EC_IOCTL_VOE_DATA EC_IOWR(0x55, ec_ioctl_voe_t) -#define EC_IOCTL_SET_SEND_INTERVAL EC_IOW(0x56, size_t) +#define EC_IOCTL_DOMAIN_SIZE EC_IO(0x41) +#define EC_IOCTL_DOMAIN_OFFSET EC_IO(0x42) +#define EC_IOCTL_DOMAIN_PROCESS EC_IO(0x43) +#define EC_IOCTL_DOMAIN_QUEUE EC_IO(0x44) +#define EC_IOCTL_DOMAIN_STATE EC_IOWR(0x45, ec_ioctl_domain_state_t) +#define EC_IOCTL_SDO_REQUEST_INDEX EC_IOWR(0x46, ec_ioctl_sdo_request_t) +#define EC_IOCTL_SDO_REQUEST_TIMEOUT EC_IOWR(0x47, ec_ioctl_sdo_request_t) +#define EC_IOCTL_SDO_REQUEST_STATE EC_IOWR(0x48, ec_ioctl_sdo_request_t) +#define EC_IOCTL_SDO_REQUEST_READ EC_IOWR(0x49, ec_ioctl_sdo_request_t) +#define EC_IOCTL_SDO_REQUEST_WRITE EC_IOWR(0x4a, ec_ioctl_sdo_request_t) +#define EC_IOCTL_SDO_REQUEST_DATA EC_IOWR(0x4b, ec_ioctl_sdo_request_t) +#define EC_IOCTL_REG_REQUEST_DATA EC_IOWR(0x4c, ec_ioctl_reg_request_t) +#define EC_IOCTL_REG_REQUEST_STATE EC_IOWR(0x4d, ec_ioctl_reg_request_t) +#define EC_IOCTL_REG_REQUEST_WRITE EC_IOWR(0x4e, ec_ioctl_reg_request_t) +#define EC_IOCTL_REG_REQUEST_READ EC_IOWR(0x4f, ec_ioctl_reg_request_t) +#define EC_IOCTL_VOE_SEND_HEADER EC_IOW(0x50, ec_ioctl_voe_t) +#define EC_IOCTL_VOE_REC_HEADER EC_IOWR(0x51, ec_ioctl_voe_t) +#define EC_IOCTL_VOE_READ EC_IOW(0x52, ec_ioctl_voe_t) +#define EC_IOCTL_VOE_READ_NOSYNC EC_IOW(0x53, ec_ioctl_voe_t) +#define EC_IOCTL_VOE_WRITE EC_IOWR(0x54, ec_ioctl_voe_t) +#define EC_IOCTL_VOE_EXEC EC_IOWR(0x55, ec_ioctl_voe_t) +#define EC_IOCTL_VOE_DATA EC_IOWR(0x56, ec_ioctl_voe_t) +#define EC_IOCTL_SET_SEND_INTERVAL EC_IOW(0x57, size_t) /*****************************************************************************/