From 93dcf1c86d44131f3e81baed254e13c4092f3724 Mon Sep 17 00:00:00 2001 From: Florian Pose Date: Fri, 4 Aug 2006 09:53:14 +0000 Subject: [PATCH] Master information, timing. --- master/master.c | 71 ++++++++++++++++++++++++++++++++++++++----------- master/master.h | 12 ++++++--- 2 files changed, 63 insertions(+), 20 deletions(-) diff --git a/master/master.c b/master/master.c index 52e16b25..6b29f35b 100644 --- a/master/master.c +++ b/master/master.c @@ -65,14 +65,12 @@ ssize_t ec_store_master_attribute(struct kobject *, struct attribute *, /** \cond */ -EC_SYSFS_READ_ATTR(slave_count); -EC_SYSFS_READ_ATTR(mode); +EC_SYSFS_READ_ATTR(info); EC_SYSFS_READ_WRITE_ATTR(eeprom_write_enable); EC_SYSFS_READ_WRITE_ATTR(debug_level); static struct attribute *ec_def_attrs[] = { - &attr_slave_count, - &attr_mode, + &attr_info, &attr_eeprom_write_enable, &attr_debug_level, NULL, @@ -122,6 +120,8 @@ int ec_master_init(ec_master_t *master, /**< EtherCAT master */ master->internal_lock = SPIN_LOCK_UNLOCKED; master->eoe_running = 0; master->eoe_checked = 0; + master->idle_cycle_time = 0; + master->eoe_cycle_time = 0; // create workqueue if (!(master->workqueue = create_singlethread_workqueue("EtherCAT"))) { @@ -606,20 +606,25 @@ void ec_master_idle_stop(ec_master_t *master /**< EtherCAT master */) void ec_master_idle_run(void *data /**< master pointer */) { ec_master_t *master = (ec_master_t *) data; + cycles_t start, end; // aquire master lock spin_lock_bh(&master->internal_lock); + start = get_cycles(); ecrt_master_receive(master); // execute master state machine ec_fsm_execute(&master->fsm); ecrt_master_send(master); + end = get_cycles(); // release master lock spin_unlock_bh(&master->internal_lock); + master->idle_cycle_time = (u32) (end - start) * 1000 / cpu_khz; + if (master->mode == EC_MASTER_MODE_IDLE) queue_delayed_work(master->workqueue, &master->idle_work, 1); } @@ -685,6 +690,43 @@ void ec_fmmu_config(const ec_fmmu_t *fmmu, /**< FMMU */ /*****************************************************************************/ +/** + Formats master information for SysFS read access. + \return number of bytes written +*/ + +ssize_t ec_master_info(ec_master_t *master, /**< EtherCAT master */ + char *buffer /**< memory to store data */ + ) +{ + off_t off = 0; + + off += sprintf(buffer + off, "\nMode: "); + switch (master->mode) { + case EC_MASTER_MODE_ORPHANED: + off += sprintf(buffer + off, "ORPHANED"); + case EC_MASTER_MODE_IDLE: + off += sprintf(buffer + off, "IDLE"); + case EC_MASTER_MODE_OPERATION: + off += sprintf(buffer + off, "OPERATION"); + } + + off += sprintf(buffer + off, "\n\nNumber of slaves: %i\n", + master->slave_count); + + off += sprintf(buffer + off, "\nTiming [us]:\n"); + off += sprintf(buffer + off, " Idle cycle time: %u\n", + master->idle_cycle_time); + off += sprintf(buffer + off, " EoE cycle time: %u\n", + master->eoe_cycle_time); + + off += sprintf(buffer + off, "\n"); + + return off; +} + +/*****************************************************************************/ + /** Formats attribute data for SysFS read access. \return number of bytes to read @@ -697,18 +739,8 @@ ssize_t ec_show_master_attribute(struct kobject *kobj, /**< kobject */ { ec_master_t *master = container_of(kobj, ec_master_t, kobj); - if (attr == &attr_slave_count) { - return sprintf(buffer, "%i\n", master->slave_count); - } - else if (attr == &attr_mode) { - switch (master->mode) { - case EC_MASTER_MODE_ORPHANED: - return sprintf(buffer, "ORPHANED\n"); - case EC_MASTER_MODE_IDLE: - return sprintf(buffer, "IDLE\n"); - case EC_MASTER_MODE_OPERATION: - return sprintf(buffer, "OPERATION\n"); - } + if (attr == &attr_info) { + return ec_master_info(master, buffer); } else if (attr == &attr_debug_level) { return sprintf(buffer, "%i\n", master->debug_level); @@ -884,6 +916,7 @@ void ec_master_eoe_run(unsigned long data /**< master pointer */) ec_master_t *master = (ec_master_t *) data; ec_eoe_t *eoe; unsigned int active = 0; + cycles_t start, end; list_for_each_entry(eoe, &master->eoe_handlers, list) { if (ec_eoe_active(eoe)) active++; @@ -903,11 +936,15 @@ void ec_master_eoe_run(unsigned long data /**< master pointer */) goto queue_timer; // actual EoE stuff + start = get_cycles(); ecrt_master_receive(master); + list_for_each_entry(eoe, &master->eoe_handlers, list) { ec_eoe_run(eoe); } + ecrt_master_send(master); + end = get_cycles(); // release lock... if (master->mode == EC_MASTER_MODE_OPERATION) { @@ -917,6 +954,8 @@ void ec_master_eoe_run(unsigned long data /**< master pointer */) spin_unlock(&master->internal_lock); } + master->eoe_cycle_time = (u32) (end - start) * 1000 / cpu_khz; + queue_timer: master->eoe_timer.expires += HZ / EC_EOE_FREQUENCY; add_timer(&master->eoe_timer); diff --git a/master/master.h b/master/master.h index ab6fce20..3506f796 100644 --- a/master/master.h +++ b/master/master.h @@ -97,11 +97,14 @@ struct ec_master struct kobject kobj; /**< kobject */ + ec_device_t *device; /**< EtherCAT device */ + + ec_fsm_t fsm; /**< master state machine */ + ec_master_mode_t mode; /**< master mode */ + struct list_head slaves; /**< list of slaves on the bus */ unsigned int slave_count; /**< number of slaves on the bus */ - ec_device_t *device; /**< EtherCAT device */ - struct list_head datagram_queue; /**< datagram queue */ uint8_t datagram_index; /**< current datagram index */ @@ -112,14 +115,15 @@ struct ec_master struct workqueue_struct *workqueue; /**< master workqueue */ struct work_struct idle_work; /**< free run work object */ - ec_fsm_t fsm; /**< master state machine */ - ec_master_mode_t mode; /**< master mode */ + uint32_t idle_cycle_time; /**< Idle cycle time */ struct timer_list eoe_timer; /**< EoE timer object */ + uint32_t eoe_cycle_time; /**< EoE cycle time */ unsigned int eoe_running; /**< non-zero, if EoE processing is active. */ unsigned int eoe_checked; /**< non-zero, if EoE processing is not necessary. */ struct list_head eoe_handlers; /**< Ethernet-over-EtherCAT handlers */ + spinlock_t internal_lock; /**< spinlock used in idle mode */ int (*request_cb)(void *); /**< lock request callback */ void (*release_cb)(void *); /**< lock release callback */