From be4754decaf1793d41ef57c8e93b32fd8d194e53 Mon Sep 17 00:00:00 2001 From: Florian Pose Date: Thu, 1 Feb 2024 16:52:24 +0100 Subject: [PATCH 01/27] API proposal for EoE set IP. --- include/ecrt.h | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/include/ecrt.h b/include/ecrt.h index 9cdd10e1..8c211894 100644 --- a/include/ecrt.h +++ b/include/ecrt.h @@ -47,6 +47,9 @@ * - Added the ecrt_master_scan_progress() method, the * ec_master_scan_progress_t structure and the EC_HAVE_SCAN_PROGRESS * definition to check for its existence. + * - Added the ecrt_slave_config_set_ip() method, the + * ec_slave_config_ip_param_t structure and the EC_HAVE_SET_IP + * definition to check for its existence. * * Changes since version 1.5.2: * @@ -243,6 +246,11 @@ */ #define EC_HAVE_SCAN_PROGRESS +/** Defined, if the method ecrt_slave_config_set_ip() and the + * ec_slave_config_ip_param_t sttucture are available. + */ +#define EC_HAVE_SET_IP + /****************************************************************************/ /** Symbol visibility control macro. @@ -618,6 +626,31 @@ typedef enum { EC_AL_STATE_OP = 8, /**< Operational. */ } ec_al_state_t; +/****************************************************************************/ + +/** Internet protocol (IP) parameters for Ethernet-over-EtherCAT (EoE). + * + * This type is used for the input parameter of ecrt_slave_config_set_ip(). + */ +typedef struct { + uint8_t mac_address_included; + uint8_t ip_address_included; + uint8_t subnet_mask_included; + uint8_t gateway_included; + uint8_t dns_included; + uint8_t name_included; + + unsigned char mac_address[EC_ETH_ALEN]; + uint32_t ip_address; + uint32_t subnet_mask; + uint32_t gateway; + uint32_t dns; + char name[EC_MAX_HOSTNAME_SIZE]; + + // output + uint16_t result; +} ec_slave_config_ip_param_t; + /***************************************************************************** * Global functions ****************************************************************************/ @@ -1792,6 +1825,19 @@ EC_PUBLIC_API int ecrt_slave_config_flag( int32_t value /**< Value to store. */ ); +/** Sets IP parameters vor Ethernet-over-EtherCAT (EoE) operation. + * + * This method has to be called in non-realtime context before + * ecrt_master_activate(). + * + * \retval 0 Success. + * \retval <0 Error code. + */ +EC_PUBLIC_API int ecrt_slave_config_set_ip( + ec_slave_config_t *sc, /**< Slave configuration. */ + const ec_slave_config_ip_param_t *ip, /**< IP parameters. */ + ); + /***************************************************************************** * Domain methods ****************************************************************************/ From f7695cd2509d8c8e4286a4035a34fa47e17ea501 Mon Sep 17 00:00:00 2001 From: Florian Pose Date: Thu, 1 Feb 2024 17:26:30 +0100 Subject: [PATCH 02/27] Broken-down SET IP methods. --- include/ecrt.h | 108 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 76 insertions(+), 32 deletions(-) diff --git a/include/ecrt.h b/include/ecrt.h index 8c211894..7bc60acc 100644 --- a/include/ecrt.h +++ b/include/ecrt.h @@ -47,8 +47,10 @@ * - Added the ecrt_master_scan_progress() method, the * ec_master_scan_progress_t structure and the EC_HAVE_SCAN_PROGRESS * definition to check for its existence. - * - Added the ecrt_slave_config_set_ip() method, the - * ec_slave_config_ip_param_t structure and the EC_HAVE_SET_IP + * - Added the EoE configuration methods ecrt_slave_config_eoe_mac(), + * ecrt_slave_config_eoe_ip(), ecrt_slave_config_eoe_subnet(), + * ecrt_slave_config_eoe_gateway(), ecrt_slave_config_eoe_dns(), + * ecrt_slave_config_eoe_hostname() and the EC_HAVE_SET_IP * definition to check for its existence. * * Changes since version 1.5.2: @@ -246,8 +248,10 @@ */ #define EC_HAVE_SCAN_PROGRESS -/** Defined, if the method ecrt_slave_config_set_ip() and the - * ec_slave_config_ip_param_t sttucture are available. +/** Defined, if the methods ecrt_slave_config_eoe_mac(), + * ecrt_slave_config_eoe_ip(), ecrt_slave_config_eoe_subnet(), + * ecrt_slave_config_eoe_gateway(), ecrt_slave_config_eoe_dns(), + * ecrt_slave_config_eoe_hostname() are available. */ #define EC_HAVE_SET_IP @@ -626,31 +630,6 @@ typedef enum { EC_AL_STATE_OP = 8, /**< Operational. */ } ec_al_state_t; -/****************************************************************************/ - -/** Internet protocol (IP) parameters for Ethernet-over-EtherCAT (EoE). - * - * This type is used for the input parameter of ecrt_slave_config_set_ip(). - */ -typedef struct { - uint8_t mac_address_included; - uint8_t ip_address_included; - uint8_t subnet_mask_included; - uint8_t gateway_included; - uint8_t dns_included; - uint8_t name_included; - - unsigned char mac_address[EC_ETH_ALEN]; - uint32_t ip_address; - uint32_t subnet_mask; - uint32_t gateway; - uint32_t dns; - char name[EC_MAX_HOSTNAME_SIZE]; - - // output - uint16_t result; -} ec_slave_config_ip_param_t; - /***************************************************************************** * Global functions ****************************************************************************/ @@ -1825,7 +1804,7 @@ EC_PUBLIC_API int ecrt_slave_config_flag( int32_t value /**< Value to store. */ ); -/** Sets IP parameters vor Ethernet-over-EtherCAT (EoE) operation. +/** Sets the MAC address for Ethernet-over-EtherCAT (EoE) operation. * * This method has to be called in non-realtime context before * ecrt_master_activate(). @@ -1833,9 +1812,74 @@ EC_PUBLIC_API int ecrt_slave_config_flag( * \retval 0 Success. * \retval <0 Error code. */ -EC_PUBLIC_API int ecrt_slave_config_set_ip( +EC_PUBLIC_API int ecrt_slave_config_eoe_mac( ec_slave_config_t *sc, /**< Slave configuration. */ - const ec_slave_config_ip_param_t *ip, /**< IP parameters. */ + unsigned char *mac_address /**< MAC address. */ + ); + +/** Sets the IP address for Ethernet-over-EtherCAT (EoE) operation. + * + * This method has to be called in non-realtime context before + * ecrt_master_activate(). + * + * \retval 0 Success. + * \retval <0 Error code. + */ +EC_PUBLIC_API int ecrt_slave_config_eoe_ip( + ec_slave_config_t *sc, /**< Slave configuration. */ + uint32_t ip_address /**< IPv4 address. */ + ); + +/** Sets the subnet mask for Ethernet-over-EtherCAT (EoE) operation. + * + * This method has to be called in non-realtime context before + * ecrt_master_activate(). + * + * \retval 0 Success. + * \retval <0 Error code. + */ +EC_PUBLIC_API int ecrt_slave_config_eoe_subnet( + ec_slave_config_t *sc, /**< Slave configuration. */ + uint32_t subnet_mask /**< IPv4 subnet mask. */ + ); + +/** Sets the gateway address for Ethernet-over-EtherCAT (EoE) operation. + * + * This method has to be called in non-realtime context before + * ecrt_master_activate(). + * + * \retval 0 Success. + * \retval <0 Error code. + */ +EC_PUBLIC_API int ecrt_slave_config_eoe_gateway( + ec_slave_config_t *sc, /**< Slave configuration. */ + uint32_t gateway_address /**< Gateway's IPv4 address. */ + ); + +/** Sets the DNS server address for Ethernet-over-EtherCAT (EoE) operation. + * + * This method has to be called in non-realtime context before + * ecrt_master_activate(). + * + * \retval 0 Success. + * \retval <0 Error code. + */ +EC_PUBLIC_API int ecrt_slave_config_eoe_dns( + ec_slave_config_t *sc, /**< Slave configuration. */ + uint32_t dns_address /**< IPv4 address of the DNS server. */ + ); + +/** Sets the host name for Ethernet-over-EtherCAT (EoE) operation. + * + * This method has to be called in non-realtime context before + * ecrt_master_activate(). + * + * \retval 0 Success. + * \retval <0 Error code. + */ +EC_PUBLIC_API int ecrt_slave_config_eoe_hostname( + ec_slave_config_t *sc, /**< Slave configuration. */ + unsigned char *name /**< Zero-terminated hostname. */ ); /***************************************************************************** From 073c81386cdedacc2e3426576a13af2714c0789b Mon Sep 17 00:00:00 2001 From: Florian Pose Date: Mon, 5 Feb 2024 11:59:22 +0100 Subject: [PATCH 03/27] Changed names of EoE set IP methods to match subcommand names. --- include/ecrt.h | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/include/ecrt.h b/include/ecrt.h index bb3591e3..ec7ba6d3 100644 --- a/include/ecrt.h +++ b/include/ecrt.h @@ -47,10 +47,10 @@ * - Added the ecrt_master_scan_progress() method, the * ec_master_scan_progress_t structure and the EC_HAVE_SCAN_PROGRESS * definition to check for its existence. - * - Added the EoE configuration methods ecrt_slave_config_eoe_mac(), - * ecrt_slave_config_eoe_ip(), ecrt_slave_config_eoe_subnet(), - * ecrt_slave_config_eoe_gateway(), ecrt_slave_config_eoe_dns(), - * ecrt_slave_config_eoe_hostname() and the EC_HAVE_SET_IP + * - Added the EoE configuration methods 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() and the EC_HAVE_SET_IP * definition to check for its existence. * * Changes since version 1.5.2: @@ -248,10 +248,10 @@ */ #define EC_HAVE_SCAN_PROGRESS -/** Defined, if the methods ecrt_slave_config_eoe_mac(), - * ecrt_slave_config_eoe_ip(), ecrt_slave_config_eoe_subnet(), - * ecrt_slave_config_eoe_gateway(), ecrt_slave_config_eoe_dns(), - * ecrt_slave_config_eoe_hostname() are available. +/** Defined, if the methods 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() are available. */ #define EC_HAVE_SET_IP @@ -1813,7 +1813,7 @@ EC_PUBLIC_API int ecrt_slave_config_flag( int32_t value /**< Value to store. */ ); -/** Sets the MAC address for Ethernet-over-EtherCAT (EoE) operation. +/** Sets the link/MAC address for Ethernet-over-EtherCAT (EoE) operation. * * This method has to be called in non-realtime context before * ecrt_master_activate(). @@ -1821,7 +1821,7 @@ EC_PUBLIC_API int ecrt_slave_config_flag( * \retval 0 Success. * \retval <0 Error code. */ -EC_PUBLIC_API int ecrt_slave_config_eoe_mac( +EC_PUBLIC_API int ecrt_slave_config_eoe_link( ec_slave_config_t *sc, /**< Slave configuration. */ unsigned char *mac_address /**< MAC address. */ ); @@ -1834,7 +1834,7 @@ EC_PUBLIC_API int ecrt_slave_config_eoe_mac( * \retval 0 Success. * \retval <0 Error code. */ -EC_PUBLIC_API int ecrt_slave_config_eoe_ip( +EC_PUBLIC_API int ecrt_slave_config_eoe_addr( ec_slave_config_t *sc, /**< Slave configuration. */ uint32_t ip_address /**< IPv4 address. */ ); @@ -1860,7 +1860,7 @@ EC_PUBLIC_API int ecrt_slave_config_eoe_subnet( * \retval 0 Success. * \retval <0 Error code. */ -EC_PUBLIC_API int ecrt_slave_config_eoe_gateway( +EC_PUBLIC_API int ecrt_slave_config_eoe_default( ec_slave_config_t *sc, /**< Slave configuration. */ uint32_t gateway_address /**< Gateway's IPv4 address. */ ); @@ -1886,7 +1886,7 @@ EC_PUBLIC_API int ecrt_slave_config_eoe_dns( * \retval 0 Success. * \retval <0 Error code. */ -EC_PUBLIC_API int ecrt_slave_config_eoe_hostname( +EC_PUBLIC_API int ecrt_slave_config_eoe_name( ec_slave_config_t *sc, /**< Slave configuration. */ unsigned char *name /**< Zero-terminated hostname. */ ); From 81e89154ae79446568a21f562ae9361588f7e486 Mon Sep 17 00:00:00 2001 From: Florian Pose Date: Mon, 5 Feb 2024 13:58:45 +0100 Subject: [PATCH 04/27] Added const for array/string parameters. --- include/ecrt.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/ecrt.h b/include/ecrt.h index ec7ba6d3..5a397349 100644 --- a/include/ecrt.h +++ b/include/ecrt.h @@ -1823,7 +1823,7 @@ EC_PUBLIC_API int ecrt_slave_config_flag( */ EC_PUBLIC_API int ecrt_slave_config_eoe_link( ec_slave_config_t *sc, /**< Slave configuration. */ - unsigned char *mac_address /**< MAC address. */ + const unsigned char *mac_address /**< MAC address. */ ); /** Sets the IP address for Ethernet-over-EtherCAT (EoE) operation. @@ -1888,7 +1888,7 @@ EC_PUBLIC_API int ecrt_slave_config_eoe_dns( */ EC_PUBLIC_API int ecrt_slave_config_eoe_name( ec_slave_config_t *sc, /**< Slave configuration. */ - unsigned char *name /**< Zero-terminated hostname. */ + const unsigned char *name /**< Zero-terminated hostname. */ ); /***************************************************************************** From 25bf7ef88592e844a40509cd4077c6a50b11eb54 Mon Sep 17 00:00:00 2001 From: Florian Pose Date: Mon, 5 Feb 2024 15:24:24 +0100 Subject: [PATCH 05/27] 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;} From 25cfa1ead17007d65dcb40e2a72257649c3b1609 Mon Sep 17 00:00:00 2001 From: Florian Pose Date: Mon, 5 Feb 2024 15:41:02 +0100 Subject: [PATCH 06/27] Fix building with --disable-eoe. --- lib/slave_config.c | 4 ++++ master/ioctl.c | 4 ++++ master/slave_config.c | 6 ++++++ tool/CommandConfig.cpp | 4 ++++ 4 files changed, 18 insertions(+) diff --git a/lib/slave_config.c b/lib/slave_config.c index f8f256c9..87483d27 100644 --- a/lib/slave_config.c +++ b/lib/slave_config.c @@ -890,6 +890,8 @@ int ecrt_slave_config_flag(ec_slave_config_t *sc, const char *key, /****************************************************************************/ +#ifdef EC_EOE + int ecrt_slave_config_eoe_link(ec_slave_config_t *sc, const unsigned char *mac_address) { @@ -1017,4 +1019,6 @@ int ecrt_slave_config_eoe_name(ec_slave_config_t *sc, return 0; } +#endif // EC_EOE + /****************************************************************************/ diff --git a/master/ioctl.c b/master/ioctl.c index 1964f29a..4f0d3855 100644 --- a/master/ioctl.c +++ b/master/ioctl.c @@ -3303,6 +3303,8 @@ static ATTRIBUTES int ec_ioctl_sc_flag( /****************************************************************************/ +#ifdef EC_EOE + /** Configures EoE IP parameters. * * \return Zero on success, otherwise a negative error code. @@ -3362,6 +3364,8 @@ static ATTRIBUTES int ec_ioctl_sc_ip( return ret; } +#endif + /****************************************************************************/ /** Gets the domain's data size. diff --git a/master/slave_config.c b/master/slave_config.c index 46e42559..c55a9eab 100644 --- a/master/slave_config.c +++ b/master/slave_config.c @@ -1434,6 +1434,8 @@ int ecrt_slave_config_flag(ec_slave_config_t *sc, const char *key, /****************************************************************************/ +#ifdef EC_EOE + int ecrt_slave_config_eoe_link(ec_slave_config_t *sc, const unsigned char *mac_address) { @@ -1489,6 +1491,8 @@ int ecrt_slave_config_eoe_name(ec_slave_config_t *sc, return 0; } +#endif + /****************************************************************************/ /** \cond */ @@ -1519,12 +1523,14 @@ 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); +#ifdef EOE 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); +#endif /** \endcond */ diff --git a/tool/CommandConfig.cpp b/tool/CommandConfig.cpp index 4374e326..67dfbc1c 100644 --- a/tool/CommandConfig.cpp +++ b/tool/CommandConfig.cpp @@ -147,7 +147,9 @@ void CommandConfig::showDetailedConfigs( ec_ioctl_config_sdo_t sdo; ec_ioctl_config_idn_t idn; ec_ioctl_config_flag_t flag; +#ifdef EC_EOE ec_ioctl_eoe_ip_t ip; +#endif string indent(doIndent ? " " : ""); for (configIter = configList.begin(); @@ -300,6 +302,7 @@ void CommandConfig::showDetailedConfigs( cout << indent << " None." << endl; } +#ifdef EC_EOE 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 @@ -351,6 +354,7 @@ void CommandConfig::showDetailedConfigs( cout << indent << " Hostname:" << ip.name << endl; } } +#endif if (configIter->dc_assign_activate) { int i; From c8ed5fa38d915c7b3448f2fe058430dd6869760f Mon Sep 17 00:00:00 2001 From: Florian Pose Date: Wed, 7 Feb 2024 12:44:55 +0100 Subject: [PATCH 07/27] Unified EoE IP parameter names. --- include/ecrt.h | 12 ++++++------ lib/Makefile.am | 6 +++++- lib/master.c | 7 +++++++ lib/slave_config.c | 24 +++++++++++++++++------- master/ioctl.c | 12 ++++++------ master/slave_config.c | 27 +++++++++++++++------------ tool/CommandIp.cpp | 25 +++++++++++++------------ 7 files changed, 69 insertions(+), 44 deletions(-) diff --git a/include/ecrt.h b/include/ecrt.h index 5a397349..7a67c27c 100644 --- a/include/ecrt.h +++ b/include/ecrt.h @@ -1821,7 +1821,7 @@ EC_PUBLIC_API int ecrt_slave_config_flag( * \retval 0 Success. * \retval <0 Error code. */ -EC_PUBLIC_API int ecrt_slave_config_eoe_link( +EC_PUBLIC_API int ecrt_slave_config_eoe_mac_address( ec_slave_config_t *sc, /**< Slave configuration. */ const unsigned char *mac_address /**< MAC address. */ ); @@ -1834,7 +1834,7 @@ EC_PUBLIC_API int ecrt_slave_config_eoe_link( * \retval 0 Success. * \retval <0 Error code. */ -EC_PUBLIC_API int ecrt_slave_config_eoe_addr( +EC_PUBLIC_API int ecrt_slave_config_eoe_ip_address( ec_slave_config_t *sc, /**< Slave configuration. */ uint32_t ip_address /**< IPv4 address. */ ); @@ -1847,7 +1847,7 @@ EC_PUBLIC_API int ecrt_slave_config_eoe_addr( * \retval 0 Success. * \retval <0 Error code. */ -EC_PUBLIC_API int ecrt_slave_config_eoe_subnet( +EC_PUBLIC_API int ecrt_slave_config_eoe_subnet_mask( ec_slave_config_t *sc, /**< Slave configuration. */ uint32_t subnet_mask /**< IPv4 subnet mask. */ ); @@ -1860,7 +1860,7 @@ EC_PUBLIC_API int ecrt_slave_config_eoe_subnet( * \retval 0 Success. * \retval <0 Error code. */ -EC_PUBLIC_API int ecrt_slave_config_eoe_default( +EC_PUBLIC_API int ecrt_slave_config_eoe_default_gateway( ec_slave_config_t *sc, /**< Slave configuration. */ uint32_t gateway_address /**< Gateway's IPv4 address. */ ); @@ -1873,7 +1873,7 @@ EC_PUBLIC_API int ecrt_slave_config_eoe_default( * \retval 0 Success. * \retval <0 Error code. */ -EC_PUBLIC_API int ecrt_slave_config_eoe_dns( +EC_PUBLIC_API int ecrt_slave_config_eoe_dns_address( ec_slave_config_t *sc, /**< Slave configuration. */ uint32_t dns_address /**< IPv4 address of the DNS server. */ ); @@ -1886,7 +1886,7 @@ EC_PUBLIC_API int ecrt_slave_config_eoe_dns( * \retval 0 Success. * \retval <0 Error code. */ -EC_PUBLIC_API int ecrt_slave_config_eoe_name( +EC_PUBLIC_API int ecrt_slave_config_eoe_hostname( ec_slave_config_t *sc, /**< Slave configuration. */ const unsigned char *name /**< Zero-terminated hostname. */ ); diff --git a/lib/Makefile.am b/lib/Makefile.am index e64c7c30..644d4ea8 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -44,7 +44,11 @@ noinst_HEADERS = \ soe_request.h \ voe_handler.h -libethercat_la_CFLAGS = -fno-strict-aliasing -Wall -I$(top_srcdir) \ +libethercat_la_CFLAGS = \ + -fno-strict-aliasing \ + -Wall \ + -Wmissing-prototypes \ + -I$(top_srcdir) \ -Dethercat_EXPORTS \ -fvisibility=hidden diff --git a/lib/master.c b/lib/master.c index f2d846e1..25dd2279 100644 --- a/lib/master.c +++ b/lib/master.c @@ -34,6 +34,13 @@ /****************************************************************************/ +// prototypes for internal lethods (avoid -Wmissing-prototype warning) +void ec_master_clear_config(ec_master_t *); +void ec_master_add_domain(ec_master_t *, ec_domain_t *); +void ec_master_add_slave_config(ec_master_t *, ec_slave_config_t *); + +/****************************************************************************/ + int ecrt_master_reserve(ec_master_t *master) { int ret = ioctl(master->fd, EC_IOCTL_REQUEST, NULL); diff --git a/lib/slave_config.c b/lib/slave_config.c index 87483d27..23223ecd 100644 --- a/lib/slave_config.c +++ b/lib/slave_config.c @@ -36,6 +36,13 @@ /****************************************************************************/ +// prototypes for internal lethods (avoid -Wmissing-prototype warning) +void ec_slave_config_add_sdo_request(ec_slave_config_t *, ec_sdo_request_t *); +void ec_slave_config_add_reg_request(ec_slave_config_t *, ec_reg_request_t *); +void ec_slave_config_add_voe_handler(ec_slave_config_t *, ec_voe_handler_t *); + +/****************************************************************************/ + void ec_slave_config_clear(ec_slave_config_t *sc) { ec_sdo_request_t *r, *next_r; @@ -612,7 +619,7 @@ ec_sdo_request_t *ecrt_slave_config_create_sdo_request(ec_slave_config_t *sc, /****************************************************************************/ -void ec_slave_config_add_soe_request(ec_slave_config_t *sc, +inline void ec_slave_config_add_soe_request(ec_slave_config_t *sc, ec_soe_request_t *req) { if (sc->first_soe_request) { @@ -892,7 +899,7 @@ int ecrt_slave_config_flag(ec_slave_config_t *sc, const char *key, #ifdef EC_EOE -int ecrt_slave_config_eoe_link(ec_slave_config_t *sc, +int ecrt_slave_config_eoe_mac_address(ec_slave_config_t *sc, const unsigned char *mac_address) { ec_ioctl_eoe_ip_t io = {}; @@ -914,7 +921,8 @@ int ecrt_slave_config_eoe_link(ec_slave_config_t *sc, /****************************************************************************/ -int ecrt_slave_config_eoe_addr(ec_slave_config_t *sc, uint32_t ip_address) +int ecrt_slave_config_eoe_ip_address(ec_slave_config_t *sc, + uint32_t ip_address) { ec_ioctl_eoe_ip_t io = {}; int ret; @@ -935,7 +943,8 @@ int ecrt_slave_config_eoe_addr(ec_slave_config_t *sc, uint32_t ip_address) /****************************************************************************/ -int ecrt_slave_config_eoe_subnet(ec_slave_config_t *sc, uint32_t subnet_mask) +int ecrt_slave_config_eoe_subnet_mask(ec_slave_config_t *sc, + uint32_t subnet_mask) { ec_ioctl_eoe_ip_t io = {}; int ret; @@ -956,7 +965,7 @@ int ecrt_slave_config_eoe_subnet(ec_slave_config_t *sc, uint32_t subnet_mask) /****************************************************************************/ -int ecrt_slave_config_eoe_default(ec_slave_config_t *sc, +int ecrt_slave_config_eoe_default_gateway(ec_slave_config_t *sc, uint32_t gateway_address) { ec_ioctl_eoe_ip_t io = {}; @@ -978,7 +987,8 @@ int ecrt_slave_config_eoe_default(ec_slave_config_t *sc, /****************************************************************************/ -int ecrt_slave_config_eoe_dns(ec_slave_config_t *sc, uint32_t dns_address) +int ecrt_slave_config_eoe_dns_address(ec_slave_config_t *sc, + uint32_t dns_address) { ec_ioctl_eoe_ip_t io = {}; int ret; @@ -999,7 +1009,7 @@ int ecrt_slave_config_eoe_dns(ec_slave_config_t *sc, uint32_t dns_address) /****************************************************************************/ -int ecrt_slave_config_eoe_name(ec_slave_config_t *sc, +int ecrt_slave_config_eoe_hostname(ec_slave_config_t *sc, const unsigned char *name) { ec_ioctl_eoe_ip_t io = {}; diff --git a/master/ioctl.c b/master/ioctl.c index 4f0d3855..f84944fb 100644 --- a/master/ioctl.c +++ b/master/ioctl.c @@ -3343,22 +3343,22 @@ static ATTRIBUTES int ec_ioctl_sc_ip( /* 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); + ecrt_slave_config_eoe_mac_address(sc, io.mac_address); } if (io.ip_address_included) { - ecrt_slave_config_eoe_addr(sc, io.ip_address); + ecrt_slave_config_eoe_ip_address(sc, io.ip_address); } if (io.subnet_mask_included) { - ecrt_slave_config_eoe_subnet(sc, io.subnet_mask); + ecrt_slave_config_eoe_subnet_mask(sc, io.subnet_mask); } if (io.gateway_included) { - ecrt_slave_config_eoe_default(sc, io.gateway); + ecrt_slave_config_eoe_default_gateway(sc, io.gateway); } if (io.dns_included) { - ecrt_slave_config_eoe_dns(sc, io.dns); + ecrt_slave_config_eoe_dns_address(sc, io.dns); } if (io.name_included) { - ecrt_slave_config_eoe_name(sc, io.name); + ecrt_slave_config_eoe_hostname(sc, io.name); } return ret; diff --git a/master/slave_config.c b/master/slave_config.c index c55a9eab..c0c813e1 100644 --- a/master/slave_config.c +++ b/master/slave_config.c @@ -1436,7 +1436,7 @@ int ecrt_slave_config_flag(ec_slave_config_t *sc, const char *key, #ifdef EC_EOE -int ecrt_slave_config_eoe_link(ec_slave_config_t *sc, +int ecrt_slave_config_eoe_mac_address(ec_slave_config_t *sc, const unsigned char *mac_address) { memcpy(sc->eoe_ip_param_request.mac_address, mac_address, EC_ETH_ALEN); @@ -1446,7 +1446,8 @@ int ecrt_slave_config_eoe_link(ec_slave_config_t *sc, /****************************************************************************/ -int ecrt_slave_config_eoe_addr(ec_slave_config_t *sc, uint32_t ip_address) +int ecrt_slave_config_eoe_ip_address(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; @@ -1455,7 +1456,8 @@ int ecrt_slave_config_eoe_addr(ec_slave_config_t *sc, uint32_t ip_address) /****************************************************************************/ -int ecrt_slave_config_eoe_subnet(ec_slave_config_t *sc, uint32_t subnet_mask) +int ecrt_slave_config_eoe_subnet_mask(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; @@ -1464,7 +1466,7 @@ int ecrt_slave_config_eoe_subnet(ec_slave_config_t *sc, uint32_t subnet_mask) /****************************************************************************/ -int ecrt_slave_config_eoe_default(ec_slave_config_t *sc, +int ecrt_slave_config_eoe_default_gateway(ec_slave_config_t *sc, uint32_t gateway_address) { sc->eoe_ip_param_request.gateway = gateway_address; @@ -1474,7 +1476,8 @@ int ecrt_slave_config_eoe_default(ec_slave_config_t *sc, /****************************************************************************/ -int ecrt_slave_config_eoe_dns(ec_slave_config_t *sc, uint32_t dns_address) +int ecrt_slave_config_eoe_dns_address(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; @@ -1483,7 +1486,7 @@ int ecrt_slave_config_eoe_dns(ec_slave_config_t *sc, uint32_t dns_address) /****************************************************************************/ -int ecrt_slave_config_eoe_name(ec_slave_config_t *sc, +int ecrt_slave_config_eoe_hostname(ec_slave_config_t *sc, const unsigned char *name) { strncpy(sc->eoe_ip_param_request.name, name, EC_MAX_HOSTNAME_SIZE); @@ -1524,12 +1527,12 @@ EXPORT_SYMBOL(ecrt_slave_config_state); EXPORT_SYMBOL(ecrt_slave_config_idn); EXPORT_SYMBOL(ecrt_slave_config_flag); #ifdef EOE -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); +EXPORT_SYMBOL(ecrt_slave_config_eoe_mac_address); +EXPORT_SYMBOL(ecrt_slave_config_eoe_ip_address); +EXPORT_SYMBOL(ecrt_slave_config_eoe_subnet_mask); +EXPORT_SYMBOL(ecrt_slave_config_eoe_default_gateway); +EXPORT_SYMBOL(ecrt_slave_config_eoe_dns_address); +EXPORT_SYMBOL(ecrt_slave_config_eoe_hostname); #endif /** \endcond */ diff --git a/tool/CommandIp.cpp b/tool/CommandIp.cpp index 7356e179..19875c88 100644 --- a/tool/CommandIp.cpp +++ b/tool/CommandIp.cpp @@ -53,13 +53,14 @@ string CommandIp::helpString(const string &binaryBaseName) const << endl << "IP parameters can be appended as argument pairs:" << endl << endl - << " addr [/prefix] IP address (optionally with" << endl - << " decimal subnet prefix)" << endl - << " link Link-layer address (may contain" << endl - << " colons or hyphens)" << endl - << " default Default gateway" << endl - << " dns DNS server" << endl - << " name Host name (max. 32 byte)" << endl + << " ip_address [/prefix] IP address (optionally with" << endl + << " decimal subnet prefix)" << endl + << " mac_address Link-layer address (may contain" + << endl + << " colons or hyphens)" << endl + << " default_gateway Default gateway" << endl + << " dns_address DNS server address" << endl + << " hostname Host name (max. 32 byte)" << endl << endl << "IPv4 adresses can be given either in dot notation or as" << endl << "hostnames, which will be automatically resolved." << endl @@ -95,23 +96,23 @@ void CommandIp::execute(const StringVector &args) string val = args[argIdx + 1]; std::transform(arg.begin(), arg.end(), arg.begin(), ::tolower); - if (arg == "link") { + if (arg == "link" or arg == "mac_address") { parseMac(io.mac_address, val); io.mac_address_included = 1; } - else if (arg == "addr") { + else if (arg == "addr" or arg == "ip_address") { parseIpv4Prefix(&io, val); io.ip_address_included = 1; } - else if (arg == "default") { + else if (arg == "default" or arg == "default_gateway") { resolveIpv4(&io.gateway, val); io.gateway_included = 1; } - else if (arg == "dns") { + else if (arg == "dns" or arg == "dns_adress") { resolveIpv4(&io.dns, val); io.dns_included = 1; } - else if (arg == "name") { + else if (arg == "name" or arg == "hostname") { if (val.size() > EC_MAX_HOSTNAME_SIZE - 1) { stringstream err; err << "Name too long!"; From a0c05e20c7409079604e20090d3c8b9f6ae70726 Mon Sep 17 00:00:00 2001 From: Florian Pose Date: Wed, 7 Feb 2024 13:16:48 +0100 Subject: [PATCH 08/27] Fixed methods in mapfile. --- lib/libethercat.map | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/libethercat.map b/lib/libethercat.map index 44178854..7a83f83b 100644 --- a/lib/libethercat.map +++ b/lib/libethercat.map @@ -104,10 +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; + ecrt_slave_config_eoe_mac_address; + ecrt_slave_config_eoe_ip_address; + ecrt_slave_config_eoe_subnet_mask; + ecrt_slave_config_eoe_default_gateway; + ecrt_slave_config_eoe_dns_address; + ecrt_slave_config_eoe_hostname; } LIBETHERCAT_1.5.3; From 156cea6a9c90e120acff2d550ddb64d94cabdc6b Mon Sep 17 00:00:00 2001 From: Florian Pose Date: Tue, 14 May 2024 15:40:26 +0200 Subject: [PATCH 09/27] Fixed typo. --- lib/master.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/master.c b/lib/master.c index af19365c..2a9018e5 100644 --- a/lib/master.c +++ b/lib/master.c @@ -34,7 +34,7 @@ /****************************************************************************/ -// prototypes for internal lethods (avoid -Wmissing-prototype warning) +// prototypes for internal methods (avoid -Wmissing-prototype warning) void ec_master_clear_config(ec_master_t *); void ec_master_add_domain(ec_master_t *, ec_domain_t *); void ec_master_add_slave_config(ec_master_t *, ec_slave_config_t *); From 5908be27b41a592e52628d7c176066046a6281fb Mon Sep 17 00:00:00 2001 From: Florian Pose Date: Tue, 14 May 2024 15:59:00 +0200 Subject: [PATCH 10/27] Fixed typo. --- lib/slave_config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/slave_config.c b/lib/slave_config.c index 8e68ed2d..42ac20a1 100644 --- a/lib/slave_config.c +++ b/lib/slave_config.c @@ -36,7 +36,7 @@ /****************************************************************************/ -// prototypes for internal lethods (avoid -Wmissing-prototype warning) +// prototypes for internal methods (avoid -Wmissing-prototype warning) void ec_slave_config_add_sdo_request(ec_slave_config_t *, ec_sdo_request_t *); void ec_slave_config_add_reg_request(ec_slave_config_t *, ec_reg_request_t *); void ec_slave_config_add_voe_handler(ec_slave_config_t *, ec_voe_handler_t *); From 0fb163ea5b253da8e4539d97c3dd500acd2f4284 Mon Sep 17 00:00:00 2001 From: Florian Pose Date: Tue, 14 May 2024 17:36:49 +0200 Subject: [PATCH 11/27] Introduced ec_eoe_request_valid(). --- master/eoe_request.c | 19 ++++++++++++++++++- master/eoe_request.h | 1 + 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/master/eoe_request.c b/master/eoe_request.c index a33e7c69..68b6d25b 100644 --- a/master/eoe_request.c +++ b/master/eoe_request.c @@ -1,6 +1,6 @@ /***************************************************************************** * - * Copyright (C) 2006-2014 Florian Pose, Ingenieurgemeinschaft IgH + * Copyright (C) 2006-2024 Florian Pose, Ingenieurgemeinschaft IgH * * This file is part of the IgH EtherCAT Master. * @@ -61,3 +61,20 @@ void ec_eoe_request_init( } /****************************************************************************/ + +/** Checks if EoE request has something to set. + */ +int ec_eoe_request_valid( + const ec_eoe_request_t *req /**< EoE request. */ + ) +{ + return + req->mac_address_included || + req->ip_address_included || + req->subnet_mask_included || + req->gateway_included || + req->dns_included || + req->name_included; +} + +/****************************************************************************/ diff --git a/master/eoe_request.h b/master/eoe_request.h index 4b9048a4..c1dcb478 100644 --- a/master/eoe_request.h +++ b/master/eoe_request.h @@ -63,6 +63,7 @@ typedef struct { /****************************************************************************/ void ec_eoe_request_init(ec_eoe_request_t *); +int ec_eoe_request_valid(const ec_eoe_request_t *); /****************************************************************************/ From bfa618ebbb0575a83255a2fc9bdd158c1da33c8a Mon Sep 17 00:00:00 2001 From: Florian Pose Date: Tue, 14 May 2024 17:52:50 +0200 Subject: [PATCH 12/27] Set EoE IP params during slave configuation. --- master/fsm_master.c | 5 +++- master/fsm_master.h | 1 + master/fsm_slave_config.c | 60 +++++++++++++++++++++++++++++++++++++-- master/fsm_slave_config.h | 7 +++-- 4 files changed, 67 insertions(+), 6 deletions(-) diff --git a/master/fsm_master.c b/master/fsm_master.c index 2828239c..3cbe802a 100644 --- a/master/fsm_master.c +++ b/master/fsm_master.c @@ -92,9 +92,11 @@ void ec_fsm_master_init( ec_fsm_coe_init(&fsm->fsm_coe); ec_fsm_soe_init(&fsm->fsm_soe); ec_fsm_pdo_init(&fsm->fsm_pdo, &fsm->fsm_coe); + ec_fsm_eoe_init(&fsm->fsm_eoe); ec_fsm_change_init(&fsm->fsm_change, fsm->datagram); ec_fsm_slave_config_init(&fsm->fsm_slave_config, fsm->datagram, - &fsm->fsm_change, &fsm->fsm_coe, &fsm->fsm_soe, &fsm->fsm_pdo); + &fsm->fsm_change, &fsm->fsm_coe, &fsm->fsm_soe, &fsm->fsm_pdo, + &fsm->fsm_eoe); ec_fsm_slave_scan_init(&fsm->fsm_slave_scan, fsm->datagram, &fsm->fsm_slave_config, &fsm->fsm_pdo); ec_fsm_sii_init(&fsm->fsm_sii, fsm->datagram); @@ -112,6 +114,7 @@ void ec_fsm_master_clear( ec_fsm_coe_clear(&fsm->fsm_coe); ec_fsm_soe_clear(&fsm->fsm_soe); ec_fsm_pdo_clear(&fsm->fsm_pdo); + ec_fsm_eoe_clear(&fsm->fsm_eoe); ec_fsm_change_clear(&fsm->fsm_change); ec_fsm_slave_config_clear(&fsm->fsm_slave_config); ec_fsm_slave_scan_clear(&fsm->fsm_slave_scan); diff --git a/master/fsm_master.h b/master/fsm_master.h index 1ffed862..d6457866 100644 --- a/master/fsm_master.h +++ b/master/fsm_master.h @@ -85,6 +85,7 @@ struct ec_fsm_master { ec_fsm_coe_t fsm_coe; /**< CoE state machine */ ec_fsm_soe_t fsm_soe; /**< SoE state machine */ ec_fsm_pdo_t fsm_pdo; /**< PDO configuration state machine. */ + ec_fsm_eoe_t fsm_eoe; /**< EoE state machine */ ec_fsm_change_t fsm_change; /**< State change state machine */ ec_fsm_slave_config_t fsm_slave_config; /**< slave state machine */ ec_fsm_slave_scan_t fsm_slave_scan; /**< slave state machine */ diff --git a/master/fsm_slave_config.c b/master/fsm_slave_config.c index 6abbd98c..f0f0d250 100644 --- a/master/fsm_slave_config.c +++ b/master/fsm_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. * @@ -67,6 +67,7 @@ void ec_fsm_slave_config_state_assign_ethercat(ec_fsm_slave_config_t *); #endif void ec_fsm_slave_config_state_sdo_conf(ec_fsm_slave_config_t *); void ec_fsm_slave_config_state_soe_conf_preop(ec_fsm_slave_config_t *); +void ec_fsm_slave_config_state_eoe_ip_param(ec_fsm_slave_config_t *); void ec_fsm_slave_config_state_watchdog_divider(ec_fsm_slave_config_t *); void ec_fsm_slave_config_state_watchdog(ec_fsm_slave_config_t *); void ec_fsm_slave_config_state_pdo_sync(ec_fsm_slave_config_t *); @@ -91,6 +92,7 @@ void ec_fsm_slave_config_enter_assign_pdi(ec_fsm_slave_config_t *); void ec_fsm_slave_config_enter_boot_preop(ec_fsm_slave_config_t *); void ec_fsm_slave_config_enter_sdo_conf(ec_fsm_slave_config_t *); void ec_fsm_slave_config_enter_soe_conf_preop(ec_fsm_slave_config_t *); +void ec_fsm_slave_config_enter_eoe_ip_param(ec_fsm_slave_config_t *); void ec_fsm_slave_config_enter_pdo_conf(ec_fsm_slave_config_t *); void ec_fsm_slave_config_enter_watchdog_divider(ec_fsm_slave_config_t *); void ec_fsm_slave_config_enter_watchdog(ec_fsm_slave_config_t *); @@ -117,7 +119,8 @@ void ec_fsm_slave_config_init( ec_fsm_change_t *fsm_change, /**< State change state machine to use. */ ec_fsm_coe_t *fsm_coe, /**< CoE state machine to use. */ ec_fsm_soe_t *fsm_soe, /**< SoE state machine to use. */ - ec_fsm_pdo_t *fsm_pdo /**< PDO configuration state machine to use. */ + ec_fsm_pdo_t *fsm_pdo, /**< PDO configuration state machine to use. */ + ec_fsm_eoe_t *fsm_eoe /**< EoE state machine to use. */ ) { ec_sdo_request_init(&fsm->request_copy); @@ -128,6 +131,7 @@ void ec_fsm_slave_config_init( fsm->fsm_coe = fsm_coe; fsm->fsm_soe = fsm_soe; fsm->fsm_pdo = fsm_pdo; + fsm->fsm_eoe = fsm_eoe; fsm->wait_ms = 0; } @@ -901,7 +905,7 @@ void ec_fsm_slave_config_enter_soe_conf_preop( } // No SoE configuration to be applied in PREOP - ec_fsm_slave_config_enter_pdo_conf(fsm); + ec_fsm_slave_config_enter_eoe_ip_param(fsm); } /****************************************************************************/ @@ -945,6 +949,56 @@ void ec_fsm_slave_config_state_soe_conf_preop( } // All PREOP IDNs are now configured. + ec_fsm_slave_config_enter_eoe_ip_param(fsm); +} + +/****************************************************************************/ + +/** EOE_IP_PARAM entry function. + */ +void ec_fsm_slave_config_enter_eoe_ip_param( + ec_fsm_slave_config_t *fsm /**< slave state machine */ + ) +{ +#if EC_EOE + ec_slave_t *slave = fsm->slave; + ec_eoe_request_t *request = &slave->config->eoe_ip_param_request; + + if (ec_eoe_request_valid(request)) { + EC_SLAVE_DBG(slave, 1, "Setting EoE IP parameters...\n"); + + // Start EoE command + fsm->state = ec_fsm_slave_config_state_eoe_ip_param; + ec_fsm_eoe_set_ip_param(fsm->fsm_eoe, slave, request); + ec_fsm_eoe_exec(fsm->fsm_eoe, fsm->datagram); // execute immediately + return; + } +#endif + + ec_fsm_slave_config_enter_pdo_conf(fsm); +} + +/****************************************************************************/ + +/** Slave configuration state: EOE_IP_PARAM. + */ +void ec_fsm_slave_config_state_eoe_ip_param( + ec_fsm_slave_config_t *fsm /**< slave state machine */ + ) +{ + ec_slave_t *slave = fsm->slave; + + if (ec_fsm_eoe_exec(fsm->fsm_eoe, fsm->datagram)) { + return; + } + + if (ec_fsm_eoe_success(fsm->fsm_eoe)) { + EC_SLAVE_DBG(slave, 1, "Finished setting EoE IP parameters.\n"); + } + else { + EC_SLAVE_ERR(slave, "Failed to set EoE IP parameters.\n"); + } + ec_fsm_slave_config_enter_pdo_conf(fsm); } diff --git a/master/fsm_slave_config.h b/master/fsm_slave_config.h index bb7566a8..fa33c83b 100644 --- a/master/fsm_slave_config.h +++ b/master/fsm_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. * @@ -34,6 +34,7 @@ #include "fsm_change.h" #include "fsm_coe.h" #include "fsm_pdo.h" +#include "fsm_eoe.h" /****************************************************************************/ @@ -49,6 +50,7 @@ struct ec_fsm_slave_config ec_fsm_coe_t *fsm_coe; /**< CoE state machine. */ ec_fsm_soe_t *fsm_soe; /**< SoE state machine. */ ec_fsm_pdo_t *fsm_pdo; /**< PDO configuration state machine. */ + ec_fsm_eoe_t *fsm_eoe; /**< EoE state machine. */ ec_slave_t *slave; /**< Slave the FSM runs on. */ void (*state)(ec_fsm_slave_config_t *); /**< State function. */ @@ -65,7 +67,8 @@ struct ec_fsm_slave_config /****************************************************************************/ void ec_fsm_slave_config_init(ec_fsm_slave_config_t *, ec_datagram_t *, - ec_fsm_change_t *, ec_fsm_coe_t *, ec_fsm_soe_t *, ec_fsm_pdo_t *); + ec_fsm_change_t *, ec_fsm_coe_t *, ec_fsm_soe_t *, ec_fsm_pdo_t *, + ec_fsm_eoe_t *); void ec_fsm_slave_config_clear(ec_fsm_slave_config_t *); void ec_fsm_slave_config_start(ec_fsm_slave_config_t *, ec_slave_t *); From cbadc30d15954a8f494be88fbd48e5fe3ebd4791 Mon Sep 17 00:00:00 2001 From: Florian Pose Date: Tue, 14 May 2024 17:53:15 +0200 Subject: [PATCH 13/27] Updated slave configuration state machine graph. --- documentation/graphs/fsm_slave_conf.dot | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/documentation/graphs/fsm_slave_conf.dot b/documentation/graphs/fsm_slave_conf.dot index cee27683..0d375538 100644 --- a/documentation/graphs/fsm_slave_conf.dot +++ b/documentation/graphs/fsm_slave_conf.dot @@ -55,12 +55,28 @@ digraph slaveconf { enter_sdo_conf [shape=point, label=""] enter_sdo_conf -> enter_pdo_sync [label="No config\nattached"] - enter_sdo_conf -> enter_pdo_conf [label="No SDOs\nconfigured"] + enter_sdo_conf -> enter_soe_conf_preop [label="No SDOs\nconfigured"] enter_sdo_conf -> sdo_conf [weight=10] sdo_conf sdo_conf -> reconfigure - sdo_conf -> enter_pdo_conf [weight=10] + sdo_conf -> enter_soe_conf_preop [weight=10] + + enter_soe_conf_preop [shape=point, label=""] + enter_soe_conf_preop -> enter_pdo_sync [label="No config\nattached"] + enter_soe_conf_preop -> enter_eoe_ip_param [label="No IDNs\nconfigured"] + enter_soe_conf_preop -> soe_conf_preop [weight=10] + + soe_conf_preop + soe_conf_preop -> reconfigure + soe_conf_preop -> enter_eoe_ip_param [weight=10] + + enter_eoe_ip_param [shape=point, label=""] + enter_eoe_ip_param -> enter_pdo_conf [label="No IP parameters"] + enter_eoe_ip_param -> eoe_ip_param [weight=10] + + eoe_ip_param + eoe_ip_param -> enter_pdo_conf [weight=10] enter_pdo_conf [shape=point, label=""] enter_pdo_conf -> pdo_conf [weight=10] From 972337444b564b04e7a169ff37da72435d730ded Mon Sep 17 00:00:00 2001 From: Florian Pose Date: Tue, 14 May 2024 18:37:17 +0200 Subject: [PATCH 14/27] Retry receiving an EoE set IP parameter response. --- master/fsm_eoe.c | 26 +++++++++++++++++++++----- master/fsm_eoe.h | 1 + 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/master/fsm_eoe.c b/master/fsm_eoe.c index 73c2ef56..abfdb781 100644 --- a/master/fsm_eoe.c +++ b/master/fsm_eoe.c @@ -61,6 +61,7 @@ void ec_fsm_eoe_init( fsm->datagram = NULL; fsm->jiffies_start = 0; fsm->request = NULL; + fsm->frame_type_retries = 0; } /****************************************************************************/ @@ -313,6 +314,7 @@ void ec_fsm_eoe_set_ip_request( ec_slave_mbox_prepare_check(slave, datagram); // can not fail. fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_eoe_set_ip_check; + fsm->frame_type_retries = 10; } /****************************************************************************/ @@ -431,11 +433,25 @@ void ec_fsm_eoe_set_ip_response( frame_type = EC_READ_U8(data) & 0x0f; if (frame_type != EC_EOE_FRAMETYPE_SET_IP_RES) { - EC_SLAVE_ERR(slave, "Received no set IP parameter response" - " (frame type %x).\n", frame_type); - ec_print_data(data, rec_size); - fsm->state = ec_fsm_eoe_error; - return; + if (master->debug_level) { + EC_SLAVE_DBG(slave, 0, "Received no set IP parameter response" + " (frame type %x).\n", frame_type); + ec_print_data(data, rec_size); + } + if (fsm->frame_type_retries--) { + // there may be an EoE segment left in the mailbox. + // discard it and receive again. + fsm->jiffies_start = fsm->datagram->jiffies_sent; + ec_slave_mbox_prepare_check(slave, datagram); // can not fail. + fsm->retries = EC_FSM_RETRIES; + fsm->state = ec_fsm_eoe_set_ip_check; + return; + } + else { + EC_SLAVE_ERR(slave, "Received no set IP parameter response.\n"); + fsm->state = ec_fsm_eoe_error; + return; + } } req->result = EC_READ_U16(data + 2); diff --git a/master/fsm_eoe.h b/master/fsm_eoe.h index 3809a462..7f901bdd 100644 --- a/master/fsm_eoe.h +++ b/master/fsm_eoe.h @@ -48,6 +48,7 @@ struct ec_fsm_eoe { ec_datagram_t *datagram; /**< Datagram used in the previous step. */ unsigned long jiffies_start; /**< Timestamp. */ ec_eoe_request_t *request; /**< EoE request */ + unsigned int frame_type_retries; /**< retries upon wrong frame type. */ }; /****************************************************************************/ From 405b8b71e17facab07dbea0ba23d74a107fe85a6 Mon Sep 17 00:00:00 2001 From: Florian Pose Date: Tue, 14 May 2024 19:00:53 +0200 Subject: [PATCH 15/27] Documentation on how to convert string-coded IP adresses. --- include/ecrt.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/include/ecrt.h b/include/ecrt.h index cc1f1d07..6589554c 100644 --- a/include/ecrt.h +++ b/include/ecrt.h @@ -1880,6 +1880,23 @@ EC_PUBLIC_API int ecrt_slave_config_eoe_mac_address( * This method has to be called in non-realtime context before * ecrt_master_activate(). * + * A string-represented IPv4 address can be converted via ithe POSIX + * function `inet_pton()` (see man 3 inet_pton): + * + * \code{.c} + * #include + * unsigned char buf[sizeof(struct in_addr)]; + * if (inet_pton(AF_INET, "192.168.0.1", buf) <= 0) { + * fprintf(stderr, "Failed to convert IP address.\n"); + * return -1; + * } + * if (ecrt_slave_config_eoe_ip_address(sc, *(uint32_t *) buf)) { + * fprintf(stderr, "Failed to set IP address.\n"); + * return -1; + * } + * \endcode + * + * * \retval 0 Success. * \retval <0 Error code. */ From 66c5793e7bc8c7c3af7482f865b3723b58603cfe Mon Sep 17 00:00:00 2001 From: Florian Pose Date: Wed, 15 May 2024 11:23:32 +0200 Subject: [PATCH 16/27] Comment. --- master/fsm_eoe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/master/fsm_eoe.c b/master/fsm_eoe.c index abfdb781..90bfa1ee 100644 --- a/master/fsm_eoe.c +++ b/master/fsm_eoe.c @@ -454,7 +454,7 @@ void ec_fsm_eoe_set_ip_response( } } - req->result = EC_READ_U16(data + 2); + req->result = EC_READ_U16(data + 2); // result code 0x0000 means success if (req->result) { fsm->state = ec_fsm_eoe_error; From c2f9baf96ae0c0619dead65e19d3ace0e66f031b Mon Sep 17 00:00:00 2001 From: Florian Pose Date: Wed, 15 May 2024 13:04:34 +0200 Subject: [PATCH 17/27] Ported API and internal structures to struct in_addr. --- include/ecrt.h | 16 +++++++++------- lib/slave_config.c | 8 ++++---- master/eoe_request.c | 8 ++++---- master/eoe_request.h | 8 ++++---- master/fsm_eoe.c | 12 ++++-------- master/ioctl.h | 8 ++++---- master/slave_config.c | 8 ++++---- tool/CommandIp.cpp | 18 ++++++------------ tool/CommandIp.h | 2 +- 9 files changed, 40 insertions(+), 48 deletions(-) diff --git a/include/ecrt.h b/include/ecrt.h index 6589554c..623b2d9d 100644 --- a/include/ecrt.h +++ b/include/ecrt.h @@ -160,10 +160,12 @@ #include #include #include +#include // struct in_addr #else #include // for size_t #include #include // for struct timeval +#include // struct in_addr #endif /***************************************************************************** @@ -1885,12 +1887,12 @@ EC_PUBLIC_API int ecrt_slave_config_eoe_mac_address( * * \code{.c} * #include - * unsigned char buf[sizeof(struct in_addr)]; - * if (inet_pton(AF_INET, "192.168.0.1", buf) <= 0) { + * struct in_addr addr; + * if (inet_aton("192.168.0.1", &addr) == 0) { * fprintf(stderr, "Failed to convert IP address.\n"); * return -1; * } - * if (ecrt_slave_config_eoe_ip_address(sc, *(uint32_t *) buf)) { + * if (ecrt_slave_config_eoe_ip_address(sc, addr)) { * fprintf(stderr, "Failed to set IP address.\n"); * return -1; * } @@ -1902,7 +1904,7 @@ EC_PUBLIC_API int ecrt_slave_config_eoe_mac_address( */ EC_PUBLIC_API int ecrt_slave_config_eoe_ip_address( ec_slave_config_t *sc, /**< Slave configuration. */ - uint32_t ip_address /**< IPv4 address. */ + struct in_addr ip_address /**< IPv4 address. */ ); /** Sets the subnet mask for Ethernet-over-EtherCAT (EoE) operation. @@ -1915,7 +1917,7 @@ EC_PUBLIC_API int ecrt_slave_config_eoe_ip_address( */ EC_PUBLIC_API int ecrt_slave_config_eoe_subnet_mask( ec_slave_config_t *sc, /**< Slave configuration. */ - uint32_t subnet_mask /**< IPv4 subnet mask. */ + struct in_addr subnet_mask /**< IPv4 subnet mask. */ ); /** Sets the gateway address for Ethernet-over-EtherCAT (EoE) operation. @@ -1928,7 +1930,7 @@ EC_PUBLIC_API int ecrt_slave_config_eoe_subnet_mask( */ EC_PUBLIC_API int ecrt_slave_config_eoe_default_gateway( ec_slave_config_t *sc, /**< Slave configuration. */ - uint32_t gateway_address /**< Gateway's IPv4 address. */ + struct in_addr gateway_address /**< Gateway's IPv4 address. */ ); /** Sets the DNS server address for Ethernet-over-EtherCAT (EoE) operation. @@ -1941,7 +1943,7 @@ EC_PUBLIC_API int ecrt_slave_config_eoe_default_gateway( */ EC_PUBLIC_API int ecrt_slave_config_eoe_dns_address( ec_slave_config_t *sc, /**< Slave configuration. */ - uint32_t dns_address /**< IPv4 address of the DNS server. */ + struct in_addr dns_address /**< IPv4 address of the DNS server. */ ); /** Sets the host name for Ethernet-over-EtherCAT (EoE) operation. diff --git a/lib/slave_config.c b/lib/slave_config.c index 42ac20a1..d64a99cd 100644 --- a/lib/slave_config.c +++ b/lib/slave_config.c @@ -928,7 +928,7 @@ int ecrt_slave_config_eoe_mac_address(ec_slave_config_t *sc, /****************************************************************************/ int ecrt_slave_config_eoe_ip_address(ec_slave_config_t *sc, - uint32_t ip_address) + struct in_addr ip_address) { ec_ioctl_eoe_ip_t io = {}; int ret; @@ -950,7 +950,7 @@ int ecrt_slave_config_eoe_ip_address(ec_slave_config_t *sc, /****************************************************************************/ int ecrt_slave_config_eoe_subnet_mask(ec_slave_config_t *sc, - uint32_t subnet_mask) + struct in_addr subnet_mask) { ec_ioctl_eoe_ip_t io = {}; int ret; @@ -972,7 +972,7 @@ int ecrt_slave_config_eoe_subnet_mask(ec_slave_config_t *sc, /****************************************************************************/ int ecrt_slave_config_eoe_default_gateway(ec_slave_config_t *sc, - uint32_t gateway_address) + struct in_addr gateway_address) { ec_ioctl_eoe_ip_t io = {}; int ret; @@ -994,7 +994,7 @@ int ecrt_slave_config_eoe_default_gateway(ec_slave_config_t *sc, /****************************************************************************/ int ecrt_slave_config_eoe_dns_address(ec_slave_config_t *sc, - uint32_t dns_address) + struct in_addr dns_address) { ec_ioctl_eoe_ip_t io = {}; int ret; diff --git a/master/eoe_request.c b/master/eoe_request.c index 68b6d25b..f336cf34 100644 --- a/master/eoe_request.c +++ b/master/eoe_request.c @@ -51,10 +51,10 @@ void ec_eoe_request_init( req->name_included = 0; memset(req->mac_address, 0x00, ETH_ALEN); - req->ip_address = 0; - req->subnet_mask = 0; - req->gateway = 0; - req->dns = 0; + req->ip_address.s_addr = 0; + req->subnet_mask.s_addr = 0; + req->gateway.s_addr = 0; + req->dns.s_addr = 0; req->name[0] = 0x00; req->result = 0x0000; diff --git a/master/eoe_request.h b/master/eoe_request.h index c1dcb478..6751f1f9 100644 --- a/master/eoe_request.h +++ b/master/eoe_request.h @@ -51,10 +51,10 @@ typedef struct { uint8_t name_included; unsigned char mac_address[ETH_ALEN]; - uint32_t ip_address; - uint32_t subnet_mask; - uint32_t gateway; - uint32_t dns; + struct in_addr ip_address; + struct in_addr subnet_mask; + struct in_addr gateway; + struct in_addr dns; char name[EC_MAX_HOSTNAME_SIZE]; uint16_t result; diff --git a/master/fsm_eoe.c b/master/fsm_eoe.c index 90bfa1ee..28964740 100644 --- a/master/fsm_eoe.c +++ b/master/fsm_eoe.c @@ -198,26 +198,22 @@ int ec_fsm_eoe_prepare_set( cur += ETH_ALEN; if (req->ip_address_included) { - uint32_t swapped = htonl(req->ip_address); - memcpy(cur, &swapped, 4); + memcpy(cur, &req->ip_address, 4); } cur += 4; if (req->subnet_mask_included) { - uint32_t swapped = htonl(req->subnet_mask); - memcpy(cur, &swapped, 4); + memcpy(cur, &req->subnet_mask, 4); } cur += 4; if (req->gateway_included) { - uint32_t swapped = htonl(req->gateway); - memcpy(cur, &swapped, 4); + memcpy(cur, &req->gateway, 4); } cur += 4; if (req->dns_included) { - uint32_t swapped = htonl(req->dns); - memcpy(cur, &swapped, 4); + memcpy(cur, &req->dns, 4); } cur += 4; diff --git a/master/ioctl.h b/master/ioctl.h index 036a6cc7..2cb90103 100644 --- a/master/ioctl.h +++ b/master/ioctl.h @@ -635,10 +635,10 @@ typedef struct { uint8_t name_included; unsigned char mac_address[EC_ETH_ALEN]; - uint32_t ip_address; - uint32_t subnet_mask; - uint32_t gateway; - uint32_t dns; + struct in_addr ip_address; + struct in_addr subnet_mask; + struct in_addr gateway; + struct in_addr dns; char name[EC_MAX_HOSTNAME_SIZE]; // output diff --git a/master/slave_config.c b/master/slave_config.c index cf94f19a..c289eda4 100644 --- a/master/slave_config.c +++ b/master/slave_config.c @@ -1453,7 +1453,7 @@ int ecrt_slave_config_eoe_mac_address(ec_slave_config_t *sc, /****************************************************************************/ int ecrt_slave_config_eoe_ip_address(ec_slave_config_t *sc, - uint32_t ip_address) + struct in_addr ip_address) { sc->eoe_ip_param_request.ip_address = ip_address; sc->eoe_ip_param_request.ip_address_included = 1; @@ -1463,7 +1463,7 @@ int ecrt_slave_config_eoe_ip_address(ec_slave_config_t *sc, /****************************************************************************/ int ecrt_slave_config_eoe_subnet_mask(ec_slave_config_t *sc, - uint32_t subnet_mask) + struct in_addr subnet_mask) { sc->eoe_ip_param_request.subnet_mask = subnet_mask; sc->eoe_ip_param_request.subnet_mask_included = 1; @@ -1473,7 +1473,7 @@ int ecrt_slave_config_eoe_subnet_mask(ec_slave_config_t *sc, /****************************************************************************/ int ecrt_slave_config_eoe_default_gateway(ec_slave_config_t *sc, - uint32_t gateway_address) + struct in_addr gateway_address) { sc->eoe_ip_param_request.gateway = gateway_address; sc->eoe_ip_param_request.gateway_included = 1; @@ -1483,7 +1483,7 @@ int ecrt_slave_config_eoe_default_gateway(ec_slave_config_t *sc, /****************************************************************************/ int ecrt_slave_config_eoe_dns_address(ec_slave_config_t *sc, - uint32_t dns_address) + struct in_addr dns_address) { sc->eoe_ip_param_request.dns = dns_address; sc->eoe_ip_param_request.dns_included = 1; diff --git a/tool/CommandIp.cpp b/tool/CommandIp.cpp index 19875c88..3c0484a5 100644 --- a/tool/CommandIp.cpp +++ b/tool/CommandIp.cpp @@ -206,11 +206,8 @@ void CommandIp::parseIpv4Prefix(ec_ioctl_eoe_ip_t *io, err << "Invalid prefix '" << prefixStr << "'!"; throwInvalidUsageException(err); } - uint32_t mask = 0; - for (unsigned int bit = 0; bit < prefix; bit++) { - mask |= (1 << (31 - bit)); - } - io->subnet_mask = htonl(mask); + uint32_t mask = (0xFFFFFFFF << (32 - prefix)) & 0xFFFFFFFF; + io->subnet_mask.s_addr = htonl(mask); } resolveIpv4(&io->ip_address, host); @@ -218,7 +215,7 @@ void CommandIp::parseIpv4Prefix(ec_ioctl_eoe_ip_t *io, /****************************************************************************/ -void CommandIp::resolveIpv4(uint32_t *addr, const string &str) +void CommandIp::resolveIpv4(struct in_addr *dst, const string &str) { struct addrinfo hints = {}; struct addrinfo *res; @@ -239,12 +236,9 @@ void CommandIp::resolveIpv4(uint32_t *addr, const string &str) throwCommandException(err.str()); } - sockaddr_in *sin = (sockaddr_in *) res->ai_addr; - for (unsigned int i = 0; i < 4; i++) { - ((unsigned char *) addr)[i] = - ((unsigned char *) &sin->sin_addr.s_addr)[i]; - } - + const struct sockaddr_in *in_addr = + (const struct sockaddr_in *) res->ai_addr; + *dst = in_addr->sin_addr; freeaddrinfo(res); } diff --git a/tool/CommandIp.h b/tool/CommandIp.h index c7e105da..bc6d9b8c 100644 --- a/tool/CommandIp.h +++ b/tool/CommandIp.h @@ -38,7 +38,7 @@ class CommandIp: protected: void parseMac(unsigned char [6], const string &); void parseIpv4Prefix(ec_ioctl_eoe_ip_t *, const string &); - void resolveIpv4(uint32_t *, const string &); + void resolveIpv4(struct in_addr *, const string &); }; /****************************************************************************/ From 5cc1aaf6cf751697f497a054b9674a704117dbd2 Mon Sep 17 00:00:00 2001 From: Florian Pose Date: Wed, 15 May 2024 13:09:05 +0200 Subject: [PATCH 18/27] Fixed method names in change list. --- include/ecrt.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/include/ecrt.h b/include/ecrt.h index 623b2d9d..5e76cb91 100644 --- a/include/ecrt.h +++ b/include/ecrt.h @@ -43,10 +43,11 @@ * - Added the ecrt_master_scan_progress() method, the * ec_master_scan_progress_t structure and the EC_HAVE_SCAN_PROGRESS * definition to check for its existence. - * - Added the EoE configuration methods 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() and the EC_HAVE_SET_IP + * - Added the EoE configuration methods ecrt_slave_config_eoe_mac_address(), + * ecrt_slave_config_eoe_ip_address(), ecrt_slave_config_eoe_subnet_mask(), + * ecrt_slave_config_eoe_default_gateway(), + * ecrt_slave_config_eoe_dns_address(), + * ecrt_slave_config_eoe_hostname() and the EC_HAVE_SET_IP * definition to check for its existence. * * Changes since version 1.5.2: From ac57cfce2495c48fd81fb08e717433c85de01702 Mon Sep 17 00:00:00 2001 From: Florian Pose Date: Wed, 15 May 2024 13:40:05 +0200 Subject: [PATCH 19/27] Fixed uninitialized variable. --- master/ioctl.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/master/ioctl.c b/master/ioctl.c index 3a5a44c7..9ca1a072 100644 --- a/master/ioctl.c +++ b/master/ioctl.c @@ -3347,7 +3347,6 @@ static ATTRIBUTES int ec_ioctl_sc_ip( ec_ioctl_eoe_ip_t io; ec_slave_config_t *sc; uint8_t *key; - int ret; if (unlikely(!ctx->requested)) { return -EPERM; @@ -3390,7 +3389,7 @@ static ATTRIBUTES int ec_ioctl_sc_ip( ecrt_slave_config_eoe_hostname(sc, io.name); } - return ret; + return 0; } #endif From a1552bdf61c81fadb65252e459a08a16d39e4085 Mon Sep 17 00:00:00 2001 From: Florian Pose Date: Wed, 15 May 2024 13:41:26 +0200 Subject: [PATCH 20/27] Use signed char as hostname type. --- include/ecrt.h | 2 +- lib/slave_config.c | 2 +- master/slave_config.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/ecrt.h b/include/ecrt.h index 5e76cb91..c27ba0d8 100644 --- a/include/ecrt.h +++ b/include/ecrt.h @@ -1957,7 +1957,7 @@ EC_PUBLIC_API int ecrt_slave_config_eoe_dns_address( */ EC_PUBLIC_API int ecrt_slave_config_eoe_hostname( ec_slave_config_t *sc, /**< Slave configuration. */ - const unsigned char *name /**< Zero-terminated hostname. */ + const char *name /**< Zero-terminated hostname. */ ); /***************************************************************************** diff --git a/lib/slave_config.c b/lib/slave_config.c index d64a99cd..7c3b8867 100644 --- a/lib/slave_config.c +++ b/lib/slave_config.c @@ -1016,7 +1016,7 @@ int ecrt_slave_config_eoe_dns_address(ec_slave_config_t *sc, /****************************************************************************/ int ecrt_slave_config_eoe_hostname(ec_slave_config_t *sc, - const unsigned char *name) + const char *name) { ec_ioctl_eoe_ip_t io = {}; int ret; diff --git a/master/slave_config.c b/master/slave_config.c index c289eda4..ccbf7abf 100644 --- a/master/slave_config.c +++ b/master/slave_config.c @@ -1493,7 +1493,7 @@ int ecrt_slave_config_eoe_dns_address(ec_slave_config_t *sc, /****************************************************************************/ int ecrt_slave_config_eoe_hostname(ec_slave_config_t *sc, - const unsigned char *name) + const char *name) { strncpy(sc->eoe_ip_param_request.name, name, EC_MAX_HOSTNAME_SIZE); sc->eoe_ip_param_request.name_included = 1; From e4588964a55f8aa76de74a60f2adaebf9bee666d Mon Sep 17 00:00:00 2001 From: Florian Pose Date: Wed, 15 May 2024 13:44:32 +0200 Subject: [PATCH 21/27] Use inet_ntop() to display configured EoE parameters. --- tool/CommandConfig.cpp | 41 ++++++++++++++--------------------------- 1 file changed, 14 insertions(+), 27 deletions(-) diff --git a/tool/CommandConfig.cpp b/tool/CommandConfig.cpp index 67dfbc1c..cf726faa 100644 --- a/tool/CommandConfig.cpp +++ b/tool/CommandConfig.cpp @@ -21,14 +21,16 @@ * ****************************************************************************/ +#include "CommandConfig.h" +#include "MasterDevice.h" + #include #include #include #include using namespace std; -#include "CommandConfig.h" -#include "MasterDevice.h" +#include /****************************************************************************/ @@ -307,6 +309,7 @@ void CommandConfig::showDetailedConfigs( 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) { + char addr[32]; cout << indent << "EoE IP parameters:" << endl; if (ip.mac_address_included) { cout << indent << " MAC address: " @@ -319,39 +322,23 @@ void CommandConfig::showDetailedConfigs( << 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; + inet_ntop(AF_INET, &ip.ip_address, addr, sizeof(addr)); + cout << indent << " IP address: " << addr << 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; + inet_ntop(AF_INET, &ip.subnet_mask, addr, sizeof(addr)); + cout << indent << " Subnet mask: " << addr << 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; + inet_ntop(AF_INET, &ip.gateway, addr, sizeof(addr)); + cout << indent << " Default gateway: " << addr << 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; + inet_ntop(AF_INET, &ip.dns, addr, sizeof(addr)); + cout << indent << " DNS server address: " << addr << endl; } if (ip.name_included) { - cout << indent << " Hostname:" << ip.name << endl; + cout << indent << " Hostname: " << ip.name << endl; } } #endif From f6f4cf74be1c0b19313fa544392e78f24a70cca9 Mon Sep 17 00:00:00 2001 From: Florian Pose Date: Wed, 15 May 2024 14:39:12 +0200 Subject: [PATCH 22/27] Fixed format string placeholder. --- master/ethernet.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/master/ethernet.c b/master/ethernet.c index 76b298df..bd755eb5 100644 --- a/master/ethernet.c +++ b/master/ethernet.c @@ -1,6 +1,6 @@ /***************************************************************************** * - * Copyright (C) 2006-2008 Florian Pose, Ingenieurgemeinschaft IgH + * Copyright (C) 2006-2024 Florian Pose, Ingenieurgemeinschaft IgH * * This file is part of the IgH EtherCAT Master. * @@ -48,6 +48,7 @@ # define SUSE_PATCHLEVEL 0 # endif #endif + /****************************************************************************/ /** Defines the debug level of EoE processing. @@ -526,7 +527,7 @@ void ec_eoe_state_rx_fetch(ec_eoe_t *eoe /**< EoE handler */) #if EOE_DEBUG_LEVEL >= 2 EC_SLAVE_DBG(eoe->slave, 0, "EoE %s RX fragment %u%s, offset %u," - " frame %u%s, %u octets\n", eoe->dev->name, fragment_number, + " frame %u%s, %zu octets\n", eoe->dev->name, fragment_number, last_fragment ? "" : "+", fragment_offset, frame_number, time_appended ? ", + timestamp" : "", time_appended ? rec_size - 8 : rec_size - 4); From dd1187d942b272f5c33957700549d73494f9cd9f Mon Sep 17 00:00:00 2001 From: Florian Pose Date: Wed, 15 May 2024 14:42:45 +0200 Subject: [PATCH 23/27] Fixed byte order. --- master/fsm_eoe.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/master/fsm_eoe.c b/master/fsm_eoe.c index 28964740..f2bce0ef 100644 --- a/master/fsm_eoe.c +++ b/master/fsm_eoe.c @@ -33,6 +33,23 @@ /****************************************************************************/ +/** Host-architecture-independent 32-bit swap function. + * + * The internal storage of struct in_addr is always big-endian. + * The mailbox protocol format to supply IPv4 adresses is little-endian + * (Yuck!). So we need a swap function, that is independent of the CPU + * architecture. ntohl()/htonl() can not be used, because they evaluate to + * NOPs if the host architecture matches the target architecture! + */ +void memcpy_swap32(void *dst, const void *src) +{ + for (int i = 0; i < 4; i++) { + ((u8 *) dst)[i] = ((const u8 *) src)[3 - i]; + } +} + +/****************************************************************************/ + /** Maximum time to wait for a set IP parameter response. */ #define EC_EOE_RESPONSE_TIMEOUT 3000 // [ms] @@ -198,22 +215,22 @@ int ec_fsm_eoe_prepare_set( cur += ETH_ALEN; if (req->ip_address_included) { - memcpy(cur, &req->ip_address, 4); + memcpy_swap32(cur, &req->ip_address); } cur += 4; if (req->subnet_mask_included) { - memcpy(cur, &req->subnet_mask, 4); + memcpy_swap32(cur, &req->subnet_mask); } cur += 4; if (req->gateway_included) { - memcpy(cur, &req->gateway, 4); + memcpy_swap32(cur, &req->gateway); } cur += 4; if (req->dns_included) { - memcpy(cur, &req->dns, 4); + memcpy_swap32(cur, &req->dns); } cur += 4; From 018863d9c7ef59056a724f7b52ff4b06056a3a98 Mon Sep 17 00:00:00 2001 From: Florian Pose Date: Wed, 15 May 2024 16:32:52 +0200 Subject: [PATCH 24/27] Avoid for loop initial declaration. --- master/fsm_eoe.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/master/fsm_eoe.c b/master/fsm_eoe.c index f2bce0ef..c061728d 100644 --- a/master/fsm_eoe.c +++ b/master/fsm_eoe.c @@ -43,7 +43,8 @@ */ void memcpy_swap32(void *dst, const void *src) { - for (int i = 0; i < 4; i++) { + int i; + for (i = 0; i < 4; i++) { ((u8 *) dst)[i] = ((const u8 *) src)[3 - i]; } } From d999311ae8225ce1d7e947f95b1500fa30049fc6 Mon Sep 17 00:00:00 2001 From: Florian Pose Date: Tue, 21 May 2024 15:40:04 +0200 Subject: [PATCH 25/27] EoE API docs. --- include/ecrt.h | 62 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 53 insertions(+), 9 deletions(-) diff --git a/include/ecrt.h b/include/ecrt.h index c27ba0d8..798f884a 100644 --- a/include/ecrt.h +++ b/include/ecrt.h @@ -247,10 +247,11 @@ */ #define EC_HAVE_SCAN_PROGRESS -/** Defined, if the methods 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() are available. +/** Defined, if the methods ecrt_slave_config_eoe_mac_address(), + * ecrt_slave_config_eoe_ip_address(), ecrt_slave_config_eoe_subnet_mask(), + * ecrt_slave_config_eoe_default_gateway(), + * ecrt_slave_config_eoe_dns_address(), ecrt_slave_config_eoe_hostname() are + * available. */ #define EC_HAVE_SET_IP @@ -1861,7 +1862,7 @@ EC_PUBLIC_API int ecrt_slave_config_idn( */ EC_PUBLIC_API int ecrt_slave_config_flag( ec_slave_config_t *sc, /**< Slave configuration. */ - const char *key, /**< Key as null-terminated ascii string. */ + const char *key, /**< Key as null-terminated ASCII string. */ int32_t value /**< Value to store. */ ); @@ -1870,6 +1871,9 @@ EC_PUBLIC_API int ecrt_slave_config_flag( * This method has to be called in non-realtime context before * ecrt_master_activate(). * + * The MAC address is stored in the slave configuration object and will be + * written to the slave during the configuration process. + * * \retval 0 Success. * \retval <0 Error code. */ @@ -1883,8 +1887,14 @@ EC_PUBLIC_API int ecrt_slave_config_eoe_mac_address( * This method has to be called in non-realtime context before * ecrt_master_activate(). * - * A string-represented IPv4 address can be converted via ithe POSIX - * function `inet_pton()` (see man 3 inet_pton): + * The IP address is stored in the slave configuration object and will be + * written to the slave during the configuration process. + * + * The IP address is passed by-value as a `struct in_addr`. This structure + * contains the 32-bit IPv4 address in network byte order (big endian). + * + * A string-represented IPv4 address can be converted to a `struct in_addr` + * for example via the POSIX function `inet_pton()` (see man 3 inet_pton): * * \code{.c} * #include @@ -1913,6 +1923,15 @@ EC_PUBLIC_API int ecrt_slave_config_eoe_ip_address( * This method has to be called in non-realtime context before * ecrt_master_activate(). * + * The subnet mask is stored in the slave configuration object and will be + * written to the slave during the configuration process. + * + * The subnet mask is passed by-value as a `struct in_addr`. This structure + * contains the 32-bit mask in network byte order (big endian). + * + * See ecrt_slave_config_eoe_ip_address() on how to convert string-coded masks + * to `struct in_addr`. + * * \retval 0 Success. * \retval <0 Error code. */ @@ -1926,6 +1945,15 @@ EC_PUBLIC_API int ecrt_slave_config_eoe_subnet_mask( * This method has to be called in non-realtime context before * ecrt_master_activate(). * + * The gateway address is stored in the slave configuration object and will be + * written to the slave during the configuration process. + * + * The address is passed by-value as a `struct in_addr`. This structure + * contains the 32-bit IPv4 address in network byte order (big endian). + * + * See ecrt_slave_config_eoe_ip_address() on how to convert string-coded IPv4 + * addresses to `struct in_addr`. + * * \retval 0 Success. * \retval <0 Error code. */ @@ -1934,11 +1962,21 @@ EC_PUBLIC_API int ecrt_slave_config_eoe_default_gateway( struct in_addr gateway_address /**< Gateway's IPv4 address. */ ); -/** Sets the DNS server address for Ethernet-over-EtherCAT (EoE) operation. +/** Sets the IPv4 address of the DNS server for Ethernet-over-EtherCAT (EoE) + * operation. * * This method has to be called in non-realtime context before * ecrt_master_activate(). * + * The DNS server address is stored in the slave configuration object and will + * be written to the slave during the configuration process. + * + * The address is passed by-value as a `struct in_addr`. This structure + * contains the 32-bit IPv4 address in network byte order (big endian). + * + * See ecrt_slave_config_eoe_ip_address() on how to convert string-coded IPv4 + * addresses to `struct in_addr`. + * * \retval 0 Success. * \retval <0 Error code. */ @@ -1952,12 +1990,18 @@ EC_PUBLIC_API int ecrt_slave_config_eoe_dns_address( * This method has to be called in non-realtime context before * ecrt_master_activate(). * + * The host name is stored in the slave configuration object and will + * be written to the slave during the configuration process. + * + * The maximum size of the host name is 32 bytes (including the zero + * terminator). + * * \retval 0 Success. * \retval <0 Error code. */ EC_PUBLIC_API int ecrt_slave_config_eoe_hostname( ec_slave_config_t *sc, /**< Slave configuration. */ - const char *name /**< Zero-terminated hostname. */ + const char *name /**< Zero-terminated host name. */ ); /***************************************************************************** From ade722eb522a503db07f7e12142f012c2ab68b5e Mon Sep 17 00:00:00 2001 From: Florian Pose Date: Tue, 21 May 2024 15:42:49 +0200 Subject: [PATCH 26/27] Limit hostname to 32 bit (including terminator) in kernel. --- master/slave_config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/master/slave_config.c b/master/slave_config.c index ccbf7abf..e331aa81 100644 --- a/master/slave_config.c +++ b/master/slave_config.c @@ -1495,7 +1495,7 @@ int ecrt_slave_config_eoe_dns_address(ec_slave_config_t *sc, int ecrt_slave_config_eoe_hostname(ec_slave_config_t *sc, const char *name) { - strncpy(sc->eoe_ip_param_request.name, name, EC_MAX_HOSTNAME_SIZE); + strncpy(sc->eoe_ip_param_request.name, name, EC_MAX_HOSTNAME_SIZE - 1); sc->eoe_ip_param_request.name_included = 1; return 0; } From dea51733107478e42da291c024e3f905d83e7e9c Mon Sep 17 00:00:00 2001 From: Florian Pose Date: Tue, 21 May 2024 15:49:21 +0200 Subject: [PATCH 27/27] Avoided warning. --- master/ioctl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/master/ioctl.c b/master/ioctl.c index 9ca1a072..a3a7bcf1 100644 --- a/master/ioctl.c +++ b/master/ioctl.c @@ -1595,6 +1595,7 @@ static ATTRIBUTES int ec_ioctl_config_ip( { ec_ioctl_eoe_ip_t *ioctl; const ec_slave_config_t *sc; + const ec_eoe_request_t *req; if (!(ioctl = kmalloc(sizeof(*ioctl), GFP_KERNEL))) { return -ENOMEM; @@ -1610,8 +1611,7 @@ static ATTRIBUTES int ec_ioctl_config_ip( return -EINTR; } - if (!(sc = ec_master_get_config_const( - master, ioctl->config_index))) { + 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); @@ -1619,7 +1619,7 @@ static ATTRIBUTES int ec_ioctl_config_ip( return -EINVAL; } - const ec_eoe_request_t *req = &sc->eoe_ip_param_request; + req = &sc->eoe_ip_param_request; ioctl->mac_address_included = req->mac_address_included; ioctl->ip_address_included = req->ip_address_included;