From 25bf7ef88592e844a40509cd4077c6a50b11eb54 Mon Sep 17 00:00:00 2001 From: Florian Pose Date: Mon, 5 Feb 2024 15:24:24 +0100 Subject: [PATCH] Set IP parameter methods on user and kernel side. --- lib/libethercat.map | 6 ++ lib/slave_config.c | 131 ++++++++++++++++++++++++++++++++++- master/ioctl.c | 145 ++++++++++++++++++++++++++++++++++++++- master/ioctl.h | 151 +++++++++++++++++++++-------------------- master/slave_config.c | 80 ++++++++++++++++++++-- master/slave_config.h | 6 +- tool/CommandConfig.cpp | 55 ++++++++++++++- tool/CommandIp.cpp | 4 +- tool/CommandIp.h | 3 +- tool/MasterDevice.cpp | 67 ++++++++++++------ tool/MasterDevice.h | 11 +-- 11 files changed, 546 insertions(+), 113 deletions(-) diff --git a/lib/libethercat.map b/lib/libethercat.map index fb1693f0..44178854 100644 --- a/lib/libethercat.map +++ b/lib/libethercat.map @@ -104,4 +104,10 @@ LIBETHERCAT_1.5.3 { LIBETHERCAT_1.6 { global: ecrt_master_scan_progress; + ecrt_slave_config_eoe_link; + ecrt_slave_config_eoe_addr; + ecrt_slave_config_eoe_subnet; + ecrt_slave_config_eoe_default; + ecrt_slave_config_eoe_dns; + ecrt_slave_config_eoe_name; } LIBETHERCAT_1.5.3; diff --git a/lib/slave_config.c b/lib/slave_config.c index 132158df..f8f256c9 100644 --- a/lib/slave_config.c +++ b/lib/slave_config.c @@ -1,6 +1,6 @@ /***************************************************************************** * - * Copyright (C) 2006-2019 Florian Pose, Ingenieurgemeinschaft IgH + * Copyright (C) 2006-2024 Florian Pose, Ingenieurgemeinschaft IgH * * This file is part of the IgH EtherCAT master userspace library. * @@ -889,3 +889,132 @@ int ecrt_slave_config_flag(ec_slave_config_t *sc, const char *key, } /****************************************************************************/ + +int ecrt_slave_config_eoe_link(ec_slave_config_t *sc, + const unsigned char *mac_address) +{ + ec_ioctl_eoe_ip_t io = {}; + int ret; + + io.config_index = sc->index; + memcpy(io.mac_address, mac_address, EC_ETH_ALEN); + io.mac_address_included = 1; + + ret = ioctl(sc->master->fd, EC_IOCTL_SC_EOE_IP_PARAM, &io); + if (EC_IOCTL_IS_ERROR(ret)) { + fprintf(stderr, "Failed to configure EoE MAC address: %s\n", + strerror(EC_IOCTL_ERRNO(ret))); + return -EC_IOCTL_ERRNO(ret); + } + + return 0; +} + +/****************************************************************************/ + +int ecrt_slave_config_eoe_addr(ec_slave_config_t *sc, uint32_t ip_address) +{ + ec_ioctl_eoe_ip_t io = {}; + int ret; + + io.config_index = sc->index; + io.ip_address = ip_address; + io.ip_address_included = 1; + + ret = ioctl(sc->master->fd, EC_IOCTL_SC_EOE_IP_PARAM, &io); + if (EC_IOCTL_IS_ERROR(ret)) { + fprintf(stderr, "Failed to configure EoE IP address: %s\n", + strerror(EC_IOCTL_ERRNO(ret))); + return -EC_IOCTL_ERRNO(ret); + } + + return 0; +} + +/****************************************************************************/ + +int ecrt_slave_config_eoe_subnet(ec_slave_config_t *sc, uint32_t subnet_mask) +{ + ec_ioctl_eoe_ip_t io = {}; + int ret; + + io.config_index = sc->index; + io.subnet_mask = subnet_mask; + io.subnet_mask_included = 1; + + ret = ioctl(sc->master->fd, EC_IOCTL_SC_EOE_IP_PARAM, &io); + if (EC_IOCTL_IS_ERROR(ret)) { + fprintf(stderr, "Failed to configure EoE subnet mask: %s\n", + strerror(EC_IOCTL_ERRNO(ret))); + return -EC_IOCTL_ERRNO(ret); + } + + return 0; +} + +/****************************************************************************/ + +int ecrt_slave_config_eoe_default(ec_slave_config_t *sc, + uint32_t gateway_address) +{ + ec_ioctl_eoe_ip_t io = {}; + int ret; + + io.config_index = sc->index; + io.gateway = gateway_address; + io.gateway_included = 1; + + ret = ioctl(sc->master->fd, EC_IOCTL_SC_EOE_IP_PARAM, &io); + if (EC_IOCTL_IS_ERROR(ret)) { + fprintf(stderr, "Failed to configure EoE default gateway: %s\n", + strerror(EC_IOCTL_ERRNO(ret))); + return -EC_IOCTL_ERRNO(ret); + } + + return 0; +} + +/****************************************************************************/ + +int ecrt_slave_config_eoe_dns(ec_slave_config_t *sc, uint32_t dns_address) +{ + ec_ioctl_eoe_ip_t io = {}; + int ret; + + io.config_index = sc->index; + io.dns = dns_address; + io.dns_included = 1; + + ret = ioctl(sc->master->fd, EC_IOCTL_SC_EOE_IP_PARAM, &io); + if (EC_IOCTL_IS_ERROR(ret)) { + fprintf(stderr, "Failed to configure EoE DNS address: %s\n", + strerror(EC_IOCTL_ERRNO(ret))); + return -EC_IOCTL_ERRNO(ret); + } + + return 0; +} + +/****************************************************************************/ + +int ecrt_slave_config_eoe_name(ec_slave_config_t *sc, + const unsigned char *name) +{ + ec_ioctl_eoe_ip_t io = {}; + int ret; + + io.config_index = sc->index; + strncpy(io.name, (const char *) name, EC_MAX_HOSTNAME_SIZE - 1); + io.name_included = 1; + + ret = ioctl(sc->master->fd, EC_IOCTL_SC_EOE_IP_PARAM, &io); + if (EC_IOCTL_IS_ERROR(ret)) { + fprintf(stderr, "Failed to configure EoE hostname: %s\n", + strerror(EC_IOCTL_ERRNO(ret))); + return -EC_IOCTL_ERRNO(ret); + } + + return 0; +} + +/****************************************************************************/ diff --git a/master/ioctl.c b/master/ioctl.c index 394dee15..1964f29a 100644 --- a/master/ioctl.c +++ b/master/ioctl.c @@ -1578,6 +1578,74 @@ static ATTRIBUTES int ec_ioctl_config_flag( #ifdef EC_EOE +/** Get configured EoE IP parameters for a given slave configuration. + * + * \return Zero on success, otherwise a negative error code. + */ +static ATTRIBUTES int ec_ioctl_config_ip( + ec_master_t *master, /**< EtherCAT master. */ + void *arg /**< ioctl() argument. */ + ) +{ + ec_ioctl_eoe_ip_t *ioctl; + const ec_slave_config_t *sc; + + if (!(ioctl = kmalloc(sizeof(*ioctl), GFP_KERNEL))) { + return -ENOMEM; + } + + if (copy_from_user(ioctl, (void __user *) arg, sizeof(*ioctl))) { + kfree(ioctl); + return -EFAULT; + } + + if (down_interruptible(&master->master_sem)) { + kfree(ioctl); + return -EINTR; + } + + if (!(sc = ec_master_get_config_const( + master, ioctl->config_index))) { + up(&master->master_sem); + EC_MASTER_ERR(master, "Slave config %u does not exist!\n", + ioctl->config_index); + kfree(ioctl); + return -EINVAL; + } + + const ec_eoe_request_t *req = &sc->eoe_ip_param_request; + + ioctl->mac_address_included = req->mac_address_included; + ioctl->ip_address_included = req->ip_address_included; + ioctl->subnet_mask_included = req->subnet_mask_included; + ioctl->gateway_included = req->gateway_included; + ioctl->dns_included = req->dns_included; + ioctl->name_included = req->name_included; + + memcpy(ioctl->mac_address, req->mac_address, EC_ETH_ALEN); + ioctl->ip_address = req->ip_address; + ioctl->subnet_mask = req->subnet_mask; + ioctl->gateway = req->gateway; + ioctl->dns = req->dns; + strncpy(ioctl->name, req->name, EC_MAX_HOSTNAME_SIZE); + + up(&master->master_sem); + + if (copy_to_user((void __user *) arg, ioctl, sizeof(*ioctl))) { + kfree(ioctl); + return -EFAULT; + } + + kfree(ioctl); + return 0; +} + +#endif + +/****************************************************************************/ + +#ifdef EC_EOE + /** Get EoE handler information. * * \return Zero on success, otherwise a negative error code. @@ -1640,7 +1708,7 @@ static ATTRIBUTES int ec_ioctl_slave_eoe_ip_param( void *arg /**< ioctl() argument. */ ) { - ec_ioctl_slave_eoe_ip_t io; + ec_ioctl_eoe_ip_t io; ec_eoe_request_t req; ec_slave_t *slave; @@ -1658,7 +1726,7 @@ static ATTRIBUTES int ec_ioctl_slave_eoe_ip_param( req.dns_included = io.dns_included; req.name_included = io.name_included; - memcpy(req.mac_address, io.mac_address, ETH_ALEN); + memcpy(req.mac_address, io.mac_address, EC_ETH_ALEN); req.ip_address = io.ip_address; req.subnet_mask = io.subnet_mask; req.gateway = io.gateway; @@ -3235,6 +3303,67 @@ static ATTRIBUTES int ec_ioctl_sc_flag( /****************************************************************************/ +/** Configures EoE IP parameters. + * + * \return Zero on success, otherwise a negative error code. + */ +static ATTRIBUTES int ec_ioctl_sc_ip( + ec_master_t *master, /**< EtherCAT master. */ + void *arg, /**< ioctl() argument. */ + ec_ioctl_context_t *ctx /**< Private data structure of file handle. */ + ) +{ + ec_ioctl_eoe_ip_t io; + ec_slave_config_t *sc; + uint8_t *key; + int ret; + + if (unlikely(!ctx->requested)) { + return -EPERM; + } + + if (copy_from_user(&io, (void __user *) arg, sizeof(io))) { + return -EFAULT; + } + + if (down_interruptible(&master->master_sem)) { + kfree(key); + return -EINTR; + } + + if (!(sc = ec_master_get_config(master, io.config_index))) { + up(&master->master_sem); + kfree(key); + return -ENOENT; + } + + up(&master->master_sem); /** \todo sc could be invalidated */ + + /* the kernel versions of the EoE set IP methods never fail. */ + if (io.mac_address_included) { + ecrt_slave_config_eoe_link(sc, io.mac_address); + } + if (io.ip_address_included) { + ecrt_slave_config_eoe_addr(sc, io.ip_address); + } + if (io.subnet_mask_included) { + ecrt_slave_config_eoe_subnet(sc, io.subnet_mask); + } + if (io.gateway_included) { + ecrt_slave_config_eoe_default(sc, io.gateway); + } + if (io.dns_included) { + ecrt_slave_config_eoe_dns(sc, io.dns); + } + if (io.name_included) { + ecrt_slave_config_eoe_name(sc, io.name); + } + + return ret; +} + +/****************************************************************************/ + /** Gets the domain's data size. * * \return Domain size, or a negative error code. @@ -5137,6 +5266,9 @@ static long ec_ioctl_nrt ret = ec_ioctl_config_flag(master, arg); break; #ifdef EC_EOE + case EC_IOCTL_CONFIG_EOE_IP_PARAM: + ret = ec_ioctl_config_ip(master, arg); + break; case EC_IOCTL_EOE_HANDLER: ret = ec_ioctl_eoe_handler(master, arg); break; @@ -5309,6 +5441,15 @@ static long ec_ioctl_nrt } ret = ec_ioctl_sc_flag(master, arg, ctx); break; +#ifdef EC_EOE + case EC_IOCTL_SC_EOE_IP_PARAM: + if (!ctx->writable) { + ret = -EPERM; + break; + } + ret = ec_ioctl_sc_ip(master, arg, ctx); + break; +#endif case EC_IOCTL_DOMAIN_SIZE: ret = ec_ioctl_domain_size(master, arg, ctx); break; diff --git a/master/ioctl.h b/master/ioctl.h index afaf62c6..036a6cc7 100644 --- a/master/ioctl.h +++ b/master/ioctl.h @@ -1,6 +1,6 @@ /***************************************************************************** * - * Copyright (C) 2006-2021 Florian Pose, Ingenieurgemeinschaft IgH + * Copyright (C) 2006-2024 Florian Pose, Ingenieurgemeinschaft IgH * * This file is part of the IgH EtherCAT master. * @@ -47,7 +47,7 @@ * * Increment this when changing the ioctl interface! */ -#define EC_IOCTL_VERSION_MAGIC 35 +#define EC_IOCTL_VERSION_MAGIC 36 // Command-line tool #define EC_IOCTL_MODULE EC_IOR(0x00, ec_ioctl_module_t) @@ -75,7 +75,7 @@ #define EC_IOCTL_SLAVE_SOE_READ EC_IOWR(0x16, ec_ioctl_slave_soe_read_t) #define EC_IOCTL_SLAVE_SOE_WRITE EC_IOWR(0x17, ec_ioctl_slave_soe_write_t) #ifdef EC_EOE -#define EC_IOCTL_SLAVE_EOE_IP_PARAM EC_IOW(0x18, ec_ioctl_slave_eoe_ip_t) +#define EC_IOCTL_SLAVE_EOE_IP_PARAM EC_IOW(0x18, ec_ioctl_eoe_ip_t) #endif #define EC_IOCTL_CONFIG EC_IOWR(0x19, ec_ioctl_config_t) #define EC_IOCTL_CONFIG_PDO EC_IOWR(0x1a, ec_ioctl_config_pdo_t) @@ -84,78 +84,82 @@ #define EC_IOCTL_CONFIG_IDN EC_IOWR(0x1d, ec_ioctl_config_idn_t) #define EC_IOCTL_CONFIG_FLAG EC_IOWR(0x1e, ec_ioctl_config_flag_t) #ifdef EC_EOE -#define EC_IOCTL_EOE_HANDLER EC_IOWR(0x1f, ec_ioctl_eoe_handler_t) +#define EC_IOCTL_CONFIG_EOE_IP_PARAM EC_IOWR(0x1f, ec_ioctl_eoe_ip_t) +#define EC_IOCTL_EOE_HANDLER EC_IOWR(0x20, ec_ioctl_eoe_handler_t) #endif // Application interface -#define EC_IOCTL_REQUEST EC_IO(0x20) -#define EC_IOCTL_CREATE_DOMAIN EC_IO(0x21) -#define EC_IOCTL_CREATE_SLAVE_CONFIG EC_IOWR(0x22, ec_ioctl_config_t) -#define EC_IOCTL_SELECT_REF_CLOCK EC_IOW(0x23, uint32_t) -#define EC_IOCTL_ACTIVATE EC_IOR(0x24, ec_ioctl_master_activate_t) -#define EC_IOCTL_DEACTIVATE EC_IO(0x25) -#define EC_IOCTL_SEND EC_IO(0x26) -#define EC_IOCTL_RECEIVE EC_IO(0x27) -#define EC_IOCTL_MASTER_STATE EC_IOR(0x28, ec_master_state_t) -#define EC_IOCTL_MASTER_LINK_STATE EC_IOWR(0x29, ec_ioctl_link_state_t) -#define EC_IOCTL_APP_TIME EC_IOW(0x2a, uint64_t) -#define EC_IOCTL_SYNC_REF EC_IO(0x2b) -#define EC_IOCTL_SYNC_REF_TO EC_IOW(0x2c, uint64_t) -#define EC_IOCTL_SYNC_SLAVES EC_IO(0x2d) -#define EC_IOCTL_REF_CLOCK_TIME EC_IOR(0x2e, uint32_t) -#define EC_IOCTL_SYNC_MON_QUEUE EC_IO(0x2f) -#define EC_IOCTL_SYNC_MON_PROCESS EC_IOR(0x30, uint32_t) -#define EC_IOCTL_RESET EC_IO(0x31) -#define EC_IOCTL_SC_SYNC EC_IOW(0x32, ec_ioctl_config_t) -#define EC_IOCTL_SC_WATCHDOG EC_IOW(0x33, ec_ioctl_config_t) -#define EC_IOCTL_SC_ADD_PDO EC_IOW(0x34, ec_ioctl_config_pdo_t) -#define EC_IOCTL_SC_CLEAR_PDOS EC_IOW(0x35, ec_ioctl_config_pdo_t) -#define EC_IOCTL_SC_ADD_ENTRY EC_IOW(0x36, ec_ioctl_add_pdo_entry_t) -#define EC_IOCTL_SC_CLEAR_ENTRIES EC_IOW(0x37, ec_ioctl_config_pdo_t) -#define EC_IOCTL_SC_REG_PDO_ENTRY EC_IOWR(0x38, ec_ioctl_reg_pdo_entry_t) -#define EC_IOCTL_SC_REG_PDO_POS EC_IOWR(0x39, ec_ioctl_reg_pdo_pos_t) -#define EC_IOCTL_SC_DC EC_IOW(0x3a, ec_ioctl_config_t) -#define EC_IOCTL_SC_SDO EC_IOW(0x3b, ec_ioctl_sc_sdo_t) -#define EC_IOCTL_SC_EMERG_SIZE EC_IOW(0x3c, ec_ioctl_sc_emerg_t) -#define EC_IOCTL_SC_EMERG_POP EC_IOWR(0x3d, ec_ioctl_sc_emerg_t) -#define EC_IOCTL_SC_EMERG_CLEAR EC_IOW(0x3e, ec_ioctl_sc_emerg_t) -#define EC_IOCTL_SC_EMERG_OVERRUNS EC_IOWR(0x3f, ec_ioctl_sc_emerg_t) -#define EC_IOCTL_SC_SDO_REQUEST EC_IOWR(0x40, ec_ioctl_sdo_request_t) -#define EC_IOCTL_SC_SOE_REQUEST EC_IOWR(0x41, ec_ioctl_soe_request_t) -#define EC_IOCTL_SC_REG_REQUEST EC_IOWR(0x42, ec_ioctl_reg_request_t) -#define EC_IOCTL_SC_VOE EC_IOWR(0x43, ec_ioctl_voe_t) -#define EC_IOCTL_SC_STATE EC_IOWR(0x44, ec_ioctl_sc_state_t) -#define EC_IOCTL_SC_IDN EC_IOW(0x45, ec_ioctl_sc_idn_t) -#define EC_IOCTL_SC_FLAG EC_IOW(0x46, ec_ioctl_sc_flag_t) -#define EC_IOCTL_DOMAIN_SIZE EC_IO(0x47) -#define EC_IOCTL_DOMAIN_OFFSET EC_IO(0x48) -#define EC_IOCTL_DOMAIN_PROCESS EC_IO(0x49) -#define EC_IOCTL_DOMAIN_QUEUE EC_IO(0x4a) -#define EC_IOCTL_DOMAIN_STATE EC_IOWR(0x4b, ec_ioctl_domain_state_t) -#define EC_IOCTL_SDO_REQUEST_INDEX EC_IOWR(0x4c, ec_ioctl_sdo_request_t) -#define EC_IOCTL_SDO_REQUEST_TIMEOUT EC_IOWR(0x4d, ec_ioctl_sdo_request_t) -#define EC_IOCTL_SDO_REQUEST_STATE EC_IOWR(0x4e, ec_ioctl_sdo_request_t) -#define EC_IOCTL_SDO_REQUEST_READ EC_IOWR(0x4f, ec_ioctl_sdo_request_t) -#define EC_IOCTL_SDO_REQUEST_WRITE EC_IOWR(0x50, ec_ioctl_sdo_request_t) -#define EC_IOCTL_SDO_REQUEST_DATA EC_IOWR(0x51, ec_ioctl_sdo_request_t) -#define EC_IOCTL_SOE_REQUEST_IDN EC_IOWR(0x52, ec_ioctl_soe_request_t) -#define EC_IOCTL_SOE_REQUEST_TIMEOUT EC_IOWR(0x53, ec_ioctl_soe_request_t) -#define EC_IOCTL_SOE_REQUEST_STATE EC_IOWR(0x54, ec_ioctl_soe_request_t) -#define EC_IOCTL_SOE_REQUEST_READ EC_IOWR(0x55, ec_ioctl_soe_request_t) -#define EC_IOCTL_SOE_REQUEST_WRITE EC_IOWR(0x56, ec_ioctl_soe_request_t) -#define EC_IOCTL_SOE_REQUEST_DATA EC_IOWR(0x57, ec_ioctl_soe_request_t) -#define EC_IOCTL_REG_REQUEST_DATA EC_IOWR(0x58, ec_ioctl_reg_request_t) -#define EC_IOCTL_REG_REQUEST_STATE EC_IOWR(0x59, ec_ioctl_reg_request_t) -#define EC_IOCTL_REG_REQUEST_WRITE EC_IOWR(0x5a, ec_ioctl_reg_request_t) -#define EC_IOCTL_REG_REQUEST_READ EC_IOWR(0x5b, ec_ioctl_reg_request_t) -#define EC_IOCTL_VOE_SEND_HEADER EC_IOW(0x5c, ec_ioctl_voe_t) -#define EC_IOCTL_VOE_REC_HEADER EC_IOWR(0x5d, ec_ioctl_voe_t) -#define EC_IOCTL_VOE_READ EC_IOW(0x5e, ec_ioctl_voe_t) -#define EC_IOCTL_VOE_READ_NOSYNC EC_IOW(0x5f, ec_ioctl_voe_t) -#define EC_IOCTL_VOE_WRITE EC_IOWR(0x60, ec_ioctl_voe_t) -#define EC_IOCTL_VOE_EXEC EC_IOWR(0x61, ec_ioctl_voe_t) -#define EC_IOCTL_VOE_DATA EC_IOWR(0x62, ec_ioctl_voe_t) -#define EC_IOCTL_SET_SEND_INTERVAL EC_IOW(0x63, size_t) +#define EC_IOCTL_REQUEST EC_IO(0x21) +#define EC_IOCTL_CREATE_DOMAIN EC_IO(0x22) +#define EC_IOCTL_CREATE_SLAVE_CONFIG EC_IOWR(0x23, ec_ioctl_config_t) +#define EC_IOCTL_SELECT_REF_CLOCK EC_IOW(0x24, uint32_t) +#define EC_IOCTL_ACTIVATE EC_IOR(0x25, ec_ioctl_master_activate_t) +#define EC_IOCTL_DEACTIVATE EC_IO(0x26) +#define EC_IOCTL_SEND EC_IO(0x27) +#define EC_IOCTL_RECEIVE EC_IO(0x28) +#define EC_IOCTL_MASTER_STATE EC_IOR(0x29, ec_master_state_t) +#define EC_IOCTL_MASTER_LINK_STATE EC_IOWR(0x2a, ec_ioctl_link_state_t) +#define EC_IOCTL_APP_TIME EC_IOW(0x2b, uint64_t) +#define EC_IOCTL_SYNC_REF EC_IO(0x2c) +#define EC_IOCTL_SYNC_REF_TO EC_IOW(0x2d, uint64_t) +#define EC_IOCTL_SYNC_SLAVES EC_IO(0x2e) +#define EC_IOCTL_REF_CLOCK_TIME EC_IOR(0x2f, uint32_t) +#define EC_IOCTL_SYNC_MON_QUEUE EC_IO(0x30) +#define EC_IOCTL_SYNC_MON_PROCESS EC_IOR(0x31, uint32_t) +#define EC_IOCTL_RESET EC_IO(0x32) +#define EC_IOCTL_SC_SYNC EC_IOW(0x33, ec_ioctl_config_t) +#define EC_IOCTL_SC_WATCHDOG EC_IOW(0x34, ec_ioctl_config_t) +#define EC_IOCTL_SC_ADD_PDO EC_IOW(0x35, ec_ioctl_config_pdo_t) +#define EC_IOCTL_SC_CLEAR_PDOS EC_IOW(0x36, ec_ioctl_config_pdo_t) +#define EC_IOCTL_SC_ADD_ENTRY EC_IOW(0x37, ec_ioctl_add_pdo_entry_t) +#define EC_IOCTL_SC_CLEAR_ENTRIES EC_IOW(0x38, ec_ioctl_config_pdo_t) +#define EC_IOCTL_SC_REG_PDO_ENTRY EC_IOWR(0x39, ec_ioctl_reg_pdo_entry_t) +#define EC_IOCTL_SC_REG_PDO_POS EC_IOWR(0x3a, ec_ioctl_reg_pdo_pos_t) +#define EC_IOCTL_SC_DC EC_IOW(0x3b, ec_ioctl_config_t) +#define EC_IOCTL_SC_SDO EC_IOW(0x3c, ec_ioctl_sc_sdo_t) +#define EC_IOCTL_SC_EMERG_SIZE EC_IOW(0x3d, ec_ioctl_sc_emerg_t) +#define EC_IOCTL_SC_EMERG_POP EC_IOWR(0x3e, ec_ioctl_sc_emerg_t) +#define EC_IOCTL_SC_EMERG_CLEAR EC_IOW(0x3f, ec_ioctl_sc_emerg_t) +#define EC_IOCTL_SC_EMERG_OVERRUNS EC_IOWR(0x40, ec_ioctl_sc_emerg_t) +#define EC_IOCTL_SC_SDO_REQUEST EC_IOWR(0x41, ec_ioctl_sdo_request_t) +#define EC_IOCTL_SC_SOE_REQUEST EC_IOWR(0x42, ec_ioctl_soe_request_t) +#define EC_IOCTL_SC_REG_REQUEST EC_IOWR(0x43, ec_ioctl_reg_request_t) +#define EC_IOCTL_SC_VOE EC_IOWR(0x44, ec_ioctl_voe_t) +#define EC_IOCTL_SC_STATE EC_IOWR(0x45, ec_ioctl_sc_state_t) +#define EC_IOCTL_SC_IDN EC_IOW(0x46, ec_ioctl_sc_idn_t) +#define EC_IOCTL_SC_FLAG EC_IOW(0x47, ec_ioctl_sc_flag_t) +#ifdef EC_EOE +#define EC_IOCTL_SC_EOE_IP_PARAM EC_IOW(0x48, ec_ioctl_eoe_ip_t) +#endif +#define EC_IOCTL_DOMAIN_SIZE EC_IO(0x49) +#define EC_IOCTL_DOMAIN_OFFSET EC_IO(0x4a) +#define EC_IOCTL_DOMAIN_PROCESS EC_IO(0x4b) +#define EC_IOCTL_DOMAIN_QUEUE EC_IO(0x4c) +#define EC_IOCTL_DOMAIN_STATE EC_IOWR(0x4d, ec_ioctl_domain_state_t) +#define EC_IOCTL_SDO_REQUEST_INDEX EC_IOWR(0x4e, ec_ioctl_sdo_request_t) +#define EC_IOCTL_SDO_REQUEST_TIMEOUT EC_IOWR(0x4f, ec_ioctl_sdo_request_t) +#define EC_IOCTL_SDO_REQUEST_STATE EC_IOWR(0x50, ec_ioctl_sdo_request_t) +#define EC_IOCTL_SDO_REQUEST_READ EC_IOWR(0x51, ec_ioctl_sdo_request_t) +#define EC_IOCTL_SDO_REQUEST_WRITE EC_IOWR(0x52, ec_ioctl_sdo_request_t) +#define EC_IOCTL_SDO_REQUEST_DATA EC_IOWR(0x53, ec_ioctl_sdo_request_t) +#define EC_IOCTL_SOE_REQUEST_IDN EC_IOWR(0x54, ec_ioctl_soe_request_t) +#define EC_IOCTL_SOE_REQUEST_TIMEOUT EC_IOWR(0x55, ec_ioctl_soe_request_t) +#define EC_IOCTL_SOE_REQUEST_STATE EC_IOWR(0x56, ec_ioctl_soe_request_t) +#define EC_IOCTL_SOE_REQUEST_READ EC_IOWR(0x57, ec_ioctl_soe_request_t) +#define EC_IOCTL_SOE_REQUEST_WRITE EC_IOWR(0x58, ec_ioctl_soe_request_t) +#define EC_IOCTL_SOE_REQUEST_DATA EC_IOWR(0x59, ec_ioctl_soe_request_t) +#define EC_IOCTL_REG_REQUEST_DATA EC_IOWR(0x5a, ec_ioctl_reg_request_t) +#define EC_IOCTL_REG_REQUEST_STATE EC_IOWR(0x5b, ec_ioctl_reg_request_t) +#define EC_IOCTL_REG_REQUEST_WRITE EC_IOWR(0x5c, ec_ioctl_reg_request_t) +#define EC_IOCTL_REG_REQUEST_READ EC_IOWR(0x5d, ec_ioctl_reg_request_t) +#define EC_IOCTL_VOE_SEND_HEADER EC_IOW(0x5e, ec_ioctl_voe_t) +#define EC_IOCTL_VOE_REC_HEADER EC_IOWR(0x5f, ec_ioctl_voe_t) +#define EC_IOCTL_VOE_READ EC_IOW(0x60, ec_ioctl_voe_t) +#define EC_IOCTL_VOE_READ_NOSYNC EC_IOW(0x61, ec_ioctl_voe_t) +#define EC_IOCTL_VOE_WRITE EC_IOWR(0x62, ec_ioctl_voe_t) +#define EC_IOCTL_VOE_EXEC EC_IOWR(0x63, ec_ioctl_voe_t) +#define EC_IOCTL_VOE_DATA EC_IOWR(0x64, ec_ioctl_voe_t) +#define EC_IOCTL_SET_SEND_INTERVAL EC_IOW(0x65, size_t) /****************************************************************************/ @@ -621,6 +625,7 @@ typedef struct { typedef struct { // input uint16_t slave_position; + uint16_t config_index; // alternatively uint8_t mac_address_included; uint8_t ip_address_included; @@ -638,7 +643,7 @@ typedef struct { // output uint16_t result; -} ec_ioctl_slave_eoe_ip_t; +} ec_ioctl_eoe_ip_t; /*****************************************************************************/ diff --git a/master/slave_config.c b/master/slave_config.c index d09d4055..46e42559 100644 --- a/master/slave_config.c +++ b/master/slave_config.c @@ -1,6 +1,6 @@ /***************************************************************************** * - * Copyright (C) 2006-2023 Florian Pose, Ingenieurgemeinschaft IgH + * Copyright (C) 2006-2024 Florian Pose, Ingenieurgemeinschaft IgH * * This file is part of the IgH EtherCAT Master. * @@ -28,15 +28,20 @@ /****************************************************************************/ -#include -#include +#include "slave_config.h" #include "globals.h" #include "master.h" #include "voe_handler.h" #include "flag.h" +#include "ioctl.h" -#include "slave_config.h" +#ifdef EC_EOE +#include "eoe_request.h" +#endif + +#include +#include /****************************************************************************/ @@ -85,6 +90,10 @@ void ec_slave_config_init( INIT_LIST_HEAD(&sc->soe_configs); INIT_LIST_HEAD(&sc->flags); +#ifdef EC_EOE + ec_eoe_request_init(&sc->eoe_ip_param_request); +#endif + ec_coe_emerg_ring_init(&sc->emerg_ring, sc); } @@ -1425,6 +1434,63 @@ int ecrt_slave_config_flag(ec_slave_config_t *sc, const char *key, /****************************************************************************/ +int ecrt_slave_config_eoe_link(ec_slave_config_t *sc, + const unsigned char *mac_address) +{ + memcpy(sc->eoe_ip_param_request.mac_address, mac_address, EC_ETH_ALEN); + sc->eoe_ip_param_request.mac_address_included = 1; + return 0; +} + +/****************************************************************************/ + +int ecrt_slave_config_eoe_addr(ec_slave_config_t *sc, uint32_t ip_address) +{ + sc->eoe_ip_param_request.ip_address = ip_address; + sc->eoe_ip_param_request.ip_address_included = 1; + return 0; +} + +/****************************************************************************/ + +int ecrt_slave_config_eoe_subnet(ec_slave_config_t *sc, uint32_t subnet_mask) +{ + sc->eoe_ip_param_request.subnet_mask = subnet_mask; + sc->eoe_ip_param_request.subnet_mask_included = 1; + return 0; +} + +/****************************************************************************/ + +int ecrt_slave_config_eoe_default(ec_slave_config_t *sc, + uint32_t gateway_address) +{ + sc->eoe_ip_param_request.gateway = gateway_address; + sc->eoe_ip_param_request.gateway_included = 1; + return 0; +} + +/****************************************************************************/ + +int ecrt_slave_config_eoe_dns(ec_slave_config_t *sc, uint32_t dns_address) +{ + sc->eoe_ip_param_request.dns = dns_address; + sc->eoe_ip_param_request.dns_included = 1; + return 0; +} + +/****************************************************************************/ + +int ecrt_slave_config_eoe_name(ec_slave_config_t *sc, + const unsigned char *name) +{ + strncpy(sc->eoe_ip_param_request.name, name, EC_MAX_HOSTNAME_SIZE); + sc->eoe_ip_param_request.name_included = 1; + return 0; +} + +/****************************************************************************/ + /** \cond */ EXPORT_SYMBOL(ecrt_slave_config_sync_manager); @@ -1453,6 +1519,12 @@ EXPORT_SYMBOL(ecrt_slave_config_create_reg_request); EXPORT_SYMBOL(ecrt_slave_config_state); EXPORT_SYMBOL(ecrt_slave_config_idn); EXPORT_SYMBOL(ecrt_slave_config_flag); +EXPORT_SYMBOL(ecrt_slave_config_eoe_link); +EXPORT_SYMBOL(ecrt_slave_config_eoe_addr); +EXPORT_SYMBOL(ecrt_slave_config_eoe_subnet); +EXPORT_SYMBOL(ecrt_slave_config_eoe_default); +EXPORT_SYMBOL(ecrt_slave_config_eoe_dns); +EXPORT_SYMBOL(ecrt_slave_config_eoe_name); /** \endcond */ diff --git a/master/slave_config.h b/master/slave_config.h index 3ddd8dd8..688156fc 100644 --- a/master/slave_config.h +++ b/master/slave_config.h @@ -1,6 +1,6 @@ /***************************************************************************** * - * Copyright (C) 2006-2023 Florian Pose, Ingenieurgemeinschaft IgH + * Copyright (C) 2006-2024 Florian Pose, Ingenieurgemeinschaft IgH * * This file is part of the IgH EtherCAT Master. * @@ -141,6 +141,10 @@ struct ec_slave_config { struct list_head soe_configs; /**< List of SoE configurations. */ struct list_head flags; /**< List of feature flags. */ +#ifdef EC_EOE + ec_eoe_request_t eoe_ip_param_request; /**< EoE IP parameters. */ +#endif + ec_coe_emerg_ring_t emerg_ring; /**< CoE emergency ring buffer. */ }; diff --git a/tool/CommandConfig.cpp b/tool/CommandConfig.cpp index 55330a4e..4374e326 100644 --- a/tool/CommandConfig.cpp +++ b/tool/CommandConfig.cpp @@ -1,6 +1,6 @@ /***************************************************************************** * - * Copyright (C) 2006-2009 Florian Pose, Ingenieurgemeinschaft IgH + * Copyright (C) 2006-2024 Florian Pose, Ingenieurgemeinschaft IgH * * This file is part of the IgH EtherCAT Master. * @@ -147,6 +147,7 @@ void CommandConfig::showDetailedConfigs( ec_ioctl_config_sdo_t sdo; ec_ioctl_config_idn_t idn; ec_ioctl_config_flag_t flag; + ec_ioctl_eoe_ip_t ip; string indent(doIndent ? " " : ""); for (configIter = configList.begin(); @@ -299,6 +300,58 @@ void CommandConfig::showDetailedConfigs( cout << indent << " None." << endl; } + m.getIpParam(&ip, configIter->config_index); + if (ip.mac_address_included or ip.ip_address_included or + ip.subnet_mask_included or ip.gateway_included or + ip.dns_included or ip.name_included) { + cout << indent << "EoE IP parameters:" << endl; + if (ip.mac_address_included) { + cout << indent << " MAC address: " + << hex << setfill('0') << setw(2) + << ip.mac_address[0] << ":" + << ip.mac_address[1] << ":" + << ip.mac_address[2] << ":" + << ip.mac_address[3] << ":" + << ip.mac_address[4] << ":" + << ip.mac_address[5] << dec << endl; + } + if (ip.ip_address_included) { + const uint8_t *addr = (const uint8_t *) &ip.ip_address; + cout << indent << " IP address: " + << (unsigned int) addr[0] << "." + << (unsigned int) addr[1] << "." + << (unsigned int) addr[2] << "." + << (unsigned int) addr[3] << endl; + } + if (ip.subnet_mask_included) { + const uint8_t *addr = (const uint8_t *) &ip.subnet_mask; + cout << indent << " Subnet mask: " + << (unsigned int) addr[0] << "." + << (unsigned int) addr[1] << "." + << (unsigned int) addr[2] << "." + << (unsigned int) addr[3] << endl; + } + if (ip.gateway_included) { + const uint8_t *addr = (const uint8_t *) &ip.gateway; + cout << indent << " Default gateway: " + << (unsigned int) addr[0] << "." + << (unsigned int) addr[1] << "." + << (unsigned int) addr[2] << "." + << (unsigned int) addr[3] << endl; + } + if (ip.dns_included) { + const uint8_t *addr = (const uint8_t *) &ip.dns; + cout << indent << " DNS server address: " + << (unsigned int) addr[0] << "." + << (unsigned int) addr[1] << "." + << (unsigned int) addr[2] << "." + << (unsigned int) addr[3] << endl; + } + if (ip.name_included) { + cout << indent << " Hostname:" << ip.name << endl; + } + } + if (configIter->dc_assign_activate) { int i; diff --git a/tool/CommandIp.cpp b/tool/CommandIp.cpp index 09a41597..7356e179 100644 --- a/tool/CommandIp.cpp +++ b/tool/CommandIp.cpp @@ -88,7 +88,7 @@ void CommandIp::execute(const StringVector &args) throwInvalidUsageException(err); } - ec_ioctl_slave_eoe_ip_t io = {}; + ec_ioctl_eoe_ip_t io = {}; for (unsigned int argIdx = 0; argIdx < args.size(); argIdx += 2) { string arg = args[argIdx]; @@ -182,7 +182,7 @@ void CommandIp::parseMac(unsigned char mac[EC_ETH_ALEN], const string &str) /****************************************************************************/ -void CommandIp::parseIpv4Prefix(ec_ioctl_slave_eoe_ip_t *io, +void CommandIp::parseIpv4Prefix(ec_ioctl_eoe_ip_t *io, const string &str) { size_t pos = str.find('/'); diff --git a/tool/CommandIp.h b/tool/CommandIp.h index da11712b..c7e105da 100644 --- a/tool/CommandIp.h +++ b/tool/CommandIp.h @@ -37,8 +37,7 @@ class CommandIp: protected: void parseMac(unsigned char [6], const string &); - void parseIpv4Prefix(ec_ioctl_slave_eoe_ip_t *, - const string &); + void parseIpv4Prefix(ec_ioctl_eoe_ip_t *, const string &); void resolveIpv4(uint32_t *, const string &); }; diff --git a/tool/MasterDevice.cpp b/tool/MasterDevice.cpp index 4d67453f..ac256d88 100644 --- a/tool/MasterDevice.cpp +++ b/tool/MasterDevice.cpp @@ -1,6 +1,6 @@ /***************************************************************************** * - * Copyright (C) 2006-2023 Florian Pose, Ingenieurgemeinschaft IgH + * Copyright (C) 2006-2024 Florian Pose, Ingenieurgemeinschaft IgH * * This file is part of the IgH EtherCAT Master. * @@ -553,26 +553,6 @@ void MasterDevice::requestState( /****************************************************************************/ -#ifdef EC_EOE - -void MasterDevice::getEoeHandler( - ec_ioctl_eoe_handler_t *eoe, - uint16_t eoeHandlerIndex - ) -{ - eoe->eoe_index = eoeHandlerIndex; - - if (ioctl(fd, EC_IOCTL_EOE_HANDLER, eoe)) { - stringstream err; - err << "Failed to get EoE handler: " << strerror(errno); - throw MasterDeviceException(err); - } -} - -#endif - -/****************************************************************************/ - void MasterDevice::readSoe(ec_ioctl_slave_soe_read_t *data) { if (ioctl(fd, EC_IOCTL_SLAVE_SOE_READ, data) < 0) { @@ -604,7 +584,49 @@ void MasterDevice::writeSoe(ec_ioctl_slave_soe_write_t *data) /****************************************************************************/ #ifdef EC_EOE -void MasterDevice::setIpParam(ec_ioctl_slave_eoe_ip_t *data) + +void MasterDevice::getEoeHandler( + ec_ioctl_eoe_handler_t *eoe, + uint16_t eoeHandlerIndex + ) +{ + eoe->eoe_index = eoeHandlerIndex; + + if (ioctl(fd, EC_IOCTL_EOE_HANDLER, eoe)) { + stringstream err; + err << "Failed to get EoE handler: " << strerror(errno); + throw MasterDeviceException(err); + } +} + +#endif + +/****************************************************************************/ + +#ifdef EC_EOE + +void MasterDevice::getIpParam(ec_ioctl_eoe_ip_t *data, uint16_t config_index) +{ + data->config_index = config_index; + + if (ioctl(fd, EC_IOCTL_CONFIG_EOE_IP_PARAM, data) < 0) { + if (errno == EIO && data->result) { + throw MasterDeviceEoeException(data->result); + } else { + stringstream err; + err << "Failed to set IP parameters: " << strerror(errno); + throw MasterDeviceException(err); + } + } +} + +#endif + +/****************************************************************************/ + +#ifdef EC_EOE + +void MasterDevice::setIpParam(ec_ioctl_eoe_ip_t *data) { if (ioctl(fd, EC_IOCTL_SLAVE_EOE_IP_PARAM, data) < 0) { if (errno == EIO && data->result) { @@ -616,6 +638,7 @@ void MasterDevice::setIpParam(ec_ioctl_slave_eoe_ip_t *data) } } } + #endif /****************************************************************************/ diff --git a/tool/MasterDevice.h b/tool/MasterDevice.h index 0643eda7..bb6c8a8e 100644 --- a/tool/MasterDevice.h +++ b/tool/MasterDevice.h @@ -1,6 +1,6 @@ /***************************************************************************** * - * Copyright (C) 2006-2009 Florian Pose, Ingenieurgemeinschaft IgH + * Copyright (C) 2006-2024 Florian Pose, Ingenieurgemeinschaft IgH * * This file is part of the IgH EtherCAT Master. * @@ -152,12 +152,13 @@ class MasterDevice void requestState(uint16_t, uint8_t); void readFoe(ec_ioctl_slave_foe_t *); void writeFoe(ec_ioctl_slave_foe_t *); -#ifdef EC_EOE - void getEoeHandler(ec_ioctl_eoe_handler_t *, uint16_t); -#endif void readSoe(ec_ioctl_slave_soe_read_t *); void writeSoe(ec_ioctl_slave_soe_write_t *); - void setIpParam(ec_ioctl_slave_eoe_ip_t *); +#ifdef EC_EOE + void getEoeHandler(ec_ioctl_eoe_handler_t *, uint16_t); + void getIpParam(ec_ioctl_eoe_ip_t *, uint16_t); + void setIpParam(ec_ioctl_eoe_ip_t *); +#endif unsigned int getMasterCount() const {return masterCount;}