Master information, timing.

This commit is contained in:
Florian Pose 2006-08-04 09:53:14 +00:00
parent a02e21fbfc
commit 93dcf1c86d
2 changed files with 63 additions and 20 deletions

View File

@ -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);

View File

@ -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 */