diff --git a/include/ecrt.h b/include/ecrt.h index 6978a37d..6055eaeb 100644 --- a/include/ecrt.h +++ b/include/ecrt.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 userspace library. * @@ -37,6 +37,12 @@ * request a master, to map process data, to communicate with slaves via CoE * and to configure and activate the bus. * + * Changes in version 1.6.0: + * + * - 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. + * * Changes since version 1.5.2: * * - Added the ecrt_slave_config_flag() method and the EC_HAVE_FLAGS @@ -213,6 +219,11 @@ */ #define EC_HAVE_SOE_REQUESTS +/** Defined, if the method ecrt_master_scan_progress() and the + * ec_master_scan_progress_t sttucture are available. + */ +#define EC_HAVE_SCAN_PROGRESS + /*****************************************************************************/ /** End of list marker. @@ -363,6 +374,21 @@ typedef struct { /*****************************************************************************/ +/** Master scan progress information. + * + * This is used as an output parameter of ecrt_master_scan_progress(). + * + * \see ecrt_master_scan_progress(). + */ +typedef struct { + unsigned int slave_count; /**< Number of slaves detected. */ + unsigned int scan_index; /**< Index of the slave that is currently scanned. + If it is less than the \a slave_count, the + network scan is in progress. */ +} ec_master_scan_progress_t; + +/*****************************************************************************/ + /** EtherCAT slave port descriptor. */ typedef enum { @@ -758,6 +784,20 @@ int ecrt_master( information */ ); +/** Obtains network scan progress information. + * + * No memory is allocated on the heap in this function. + * + * \attention The pointer to this structure must point to a valid variable. + * + * \return 0 in case of success, else < 0 + */ +int ecrt_master_scan_progress( + ec_master_t *master, /**< EtherCAT master */ + ec_master_scan_progress_t *progress /**< Structure that will output + the progress information. */ + ); + /** Obtains slave information. * * Tries to find the slave with the given ring position. The obtained diff --git a/lib/master.c b/lib/master.c index 27835018..17c14ae0 100644 --- a/lib/master.c +++ b/lib/master.c @@ -251,6 +251,26 @@ int ecrt_master(ec_master_t *master, ec_master_info_t *master_info) /****************************************************************************/ +int ecrt_master_scan_progress(ec_master_t *master, + ec_master_scan_progress_t *progress) +{ + ec_ioctl_master_t data; + int ret; + + ret = ioctl(master->fd, EC_IOCTL_MASTER, &data); + if (EC_IOCTL_IS_ERROR(ret)) { + fprintf(stderr, "Failed to get master info: %s\n", + strerror(EC_IOCTL_ERRNO(ret))); + return -EC_IOCTL_ERRNO(ret); + } + + progress->slave_count = data.slave_count; + progress->scan_index = data.scan_index; + return 0; +} + +/****************************************************************************/ + int ecrt_master_get_slave(ec_master_t *master, uint16_t slave_position, ec_slave_info_t *slave_info) { diff --git a/master/fsm_master.c b/master/fsm_master.c index 92595dda..dff4cfbb 100644 --- a/master/fsm_master.c +++ b/master/fsm_master.c @@ -339,6 +339,7 @@ void ec_fsm_master_state_broadcast( ec_device_index_t dev_idx; master->scan_busy = 1; + master->scan_index = 0; up(&master->scan_sem); // clear all slaves and scan the bus @@ -842,6 +843,7 @@ void ec_fsm_master_state_clear_addresses( ec_device_names[fsm->dev_idx != 0]); ec_datagram_print_state(datagram); master->scan_busy = 0; + master->scan_index = master->slave_count; wake_up_interruptible(&master->scan_queue); ec_fsm_master_restart(fsm); return; @@ -885,6 +887,7 @@ void ec_fsm_master_state_dc_measure_delays( " on %s link: ", ec_device_names[fsm->dev_idx != 0]); ec_datagram_print_state(datagram); master->scan_busy = 0; + master->scan_index = master->slave_count; wake_up_interruptible(&master->scan_queue); ec_fsm_master_restart(fsm); return; @@ -907,6 +910,7 @@ void ec_fsm_master_state_dc_measure_delays( // begin scanning of slaves fsm->slave = master->slaves; + master->scan_index = 0; EC_MASTER_DBG(master, 1, "Scanning slave %u on %s link.\n", fsm->slave->ring_position, ec_device_names[fsm->slave->device_index != 0]); @@ -952,6 +956,7 @@ void ec_fsm_master_state_scan_slave( // another slave to fetch? fsm->slave++; + master->scan_index++; if (fsm->slave < master->slaves + master->slave_count) { EC_MASTER_DBG(master, 1, "Scanning slave %u on %s link.\n", fsm->slave->ring_position, @@ -966,6 +971,7 @@ void ec_fsm_master_state_scan_slave( (jiffies - fsm->scan_jiffies) * 1000 / HZ); master->scan_busy = 0; + master->scan_index = master->slave_count; wake_up_interruptible(&master->scan_queue); ec_master_calc_dc(master); diff --git a/master/ioctl.c b/master/ioctl.c index 24209a74..54dd1103 100644 --- a/master/ioctl.c +++ b/master/ioctl.c @@ -112,6 +112,7 @@ static ATTRIBUTES int ec_ioctl_master( } io.slave_count = master->slave_count; + io.scan_index = master->scan_index; io.config_count = ec_master_config_count(master); io.domain_count = ec_master_domain_count(master); #ifdef EC_EOE diff --git a/master/ioctl.h b/master/ioctl.h index 20c4de6d..7a5e57b9 100644 --- a/master/ioctl.h +++ b/master/ioctl.h @@ -47,7 +47,7 @@ * * Increment this when changing the ioctl interface! */ -#define EC_IOCTL_VERSION_MAGIC 33 +#define EC_IOCTL_VERSION_MAGIC 34 // Command-line tool #define EC_IOCTL_MODULE EC_IOR(0x00, ec_ioctl_module_t) @@ -169,6 +169,7 @@ typedef struct { typedef struct { uint32_t slave_count; + uint32_t scan_index; uint32_t config_count; uint32_t domain_count; uint32_t eoe_handler_count; diff --git a/master/master.c b/master/master.c index 2adf87bf..5dd1b157 100644 --- a/master/master.c +++ b/master/master.c @@ -192,6 +192,7 @@ int ec_master_init(ec_master_t *master, /**< EtherCAT master */ master->dc_ref_time = 0ULL; master->scan_busy = 0; + master->scan_index = 0; master->allow_scan = 1; sema_init(&master->scan_sem, 1); init_waitqueue_head(&master->scan_queue); @@ -2678,6 +2679,19 @@ int ecrt_master(ec_master_t *master, ec_master_info_t *master_info) /*****************************************************************************/ +int ecrt_master_scan_progress(ec_master_t *master, + ec_master_scan_progress_t *progress) +{ + EC_MASTER_DBG(master, 1, "ecrt_master_scan_progress(master = 0x%p," + " progress = 0x%p)\n", master, progress); + + progress->slave_count = master->slave_count; + progress->scan_index = master->scan_index; + return 0; +} + +/*****************************************************************************/ + int ecrt_master_get_slave(ec_master_t *master, uint16_t slave_position, ec_slave_info_t *slave_info) { @@ -3301,6 +3315,7 @@ EXPORT_SYMBOL(ecrt_master_send_ext); EXPORT_SYMBOL(ecrt_master_receive); EXPORT_SYMBOL(ecrt_master_callbacks); EXPORT_SYMBOL(ecrt_master); +EXPORT_SYMBOL(ecrt_master_scan_progress); EXPORT_SYMBOL(ecrt_master_get_slave); EXPORT_SYMBOL(ecrt_master_slave_config); EXPORT_SYMBOL(ecrt_master_select_reference_clock); diff --git a/master/master.h b/master/master.h index c45d3bef..c72fbb04 100644 --- a/master/master.h +++ b/master/master.h @@ -1,8 +1,6 @@ /****************************************************************************** * - * $Id$ - * - * Copyright (C) 2006-2012 Florian Pose, Ingenieurgemeinschaft IgH + * Copyright (C) 2006-2024 Florian Pose, Ingenieurgemeinschaft IgH * * This file is part of the IgH EtherCAT Master. * @@ -248,6 +246,7 @@ struct ec_master { ec_slave_t *dc_ref_clock; /**< DC reference clock slave. */ unsigned int scan_busy; /**< Current scan state. */ + unsigned int scan_index; /**< Index of slave currently scanned. */ unsigned int allow_scan; /**< \a True, if slave scanning is allowed. */ struct semaphore scan_sem; /**< Semaphore protecting the \a scan_busy variable and the \a allow_scan flag. */