From f52e4c1f6af5a55ac204aca6a2ac4888ecdbbcc1 Mon Sep 17 00:00:00 2001 From: Florian Pose <fp@igh-essen.com> Date: Tue, 25 Apr 2006 13:43:13 +0000 Subject: [PATCH] Prepared EoE processing with workqueue. --- include/ecrt.h | 2 ++ master/master.c | 89 ++++++++++++++++++++++++++++++++++++++----------- master/master.h | 3 +- mini/mini.c | 23 ++++++++++++- rt/msr_rt.c | 7 ++++ 5 files changed, 103 insertions(+), 21 deletions(-) diff --git a/include/ecrt.h b/include/ecrt.h index e69b0140..f4c20f51 100644 --- a/include/ecrt.h +++ b/include/ecrt.h @@ -105,6 +105,8 @@ void ecrt_master_prepare_async_io(ec_master_t *master); void ecrt_master_run(ec_master_t *master); +int ecrt_master_start_eoe(ec_master_t *master); + void ecrt_master_debug(ec_master_t *master, int level); void ecrt_master_print(const ec_master_t *master, unsigned int verbosity); diff --git a/master/master.c b/master/master.c index 56db490d..467669c1 100644 --- a/master/master.c +++ b/master/master.c @@ -46,6 +46,7 @@ /*****************************************************************************/ void ec_master_freerun(unsigned long); +void ec_master_run_eoe(void *); ssize_t ec_show_master_attribute(struct kobject *, struct attribute *, char *); void ec_master_process_watch_command(ec_master_t *); @@ -112,6 +113,9 @@ int ec_master_init(ec_master_t *master, /**< EtherCAT master */ master->freerun_timer.function = ec_master_freerun; master->freerun_timer.data = (unsigned long) master; + master->eoe_wq = NULL; + INIT_WORK(&master->eoe_work, ec_master_run_eoe, master); + ec_command_init(&master->simple_command); ec_command_init(&master->watch_command); @@ -145,6 +149,8 @@ void ec_master_clear(struct kobject *kobj /**< kobject of the master */) ec_command_clear(&master->simple_command); ec_command_clear(&master->watch_command); + if (master->eoe_wq) destroy_workqueue(master->eoe_wq); + EC_INFO("Master %i cleared.\n", master->index); } @@ -163,6 +169,11 @@ void ec_master_reset(ec_master_t *master /**< EtherCAT master */) ec_domain_t *domain, *next_d; ec_eoe_t *eoe, *next_eoe; + // stop EoE processing + if (master->eoe_wq && !cancel_delayed_work(&master->eoe_work)) { + flush_workqueue(master->eoe_wq); + } + ec_master_freerun_stop(master); // remove all slaves @@ -485,7 +496,6 @@ int ec_master_bus_scan(ec_master_t *master /**< EtherCAT master */) ec_slave_ident_t *ident; unsigned int i; ec_command_t *command; - ec_eoe_t *eoe; uint16_t coupler_index, coupler_subindex; uint16_t reverse_coupler_index, current_coupler_index; @@ -570,20 +580,6 @@ int ec_master_bus_scan(ec_master_t *master /**< EtherCAT master */) slave->coupler_index = current_coupler_index; slave->coupler_subindex = coupler_subindex; coupler_subindex++; - - // does the slave support EoE? - if (slave->sii_mailbox_protocols & EC_MBOX_EOE) { - if (!(eoe = (ec_eoe_t *) kmalloc(sizeof(ec_eoe_t), GFP_KERNEL))) { - EC_ERR("Failed to allocate EoE-Object.\n"); - goto out_free; - } - - if (ec_eoe_init(eoe, slave)) { - kfree(eoe); - goto out_free; - } - list_add_tail(&eoe->list, &master->eoe_slaves); - } } return 0; @@ -848,13 +844,19 @@ void ec_master_process_watch_command(ec_master_t *master Does the Ethernet-over-EtherCAT processing. */ -void ec_master_run_eoe(ec_master_t *master /**< EtherCAT master */) +void ec_master_run_eoe(void *data /**< work data (= master pointer) */) { + ec_master_t *master = (ec_master_t *) data; + +#if 0 ec_eoe_t *eoe; list_for_each_entry(eoe, &master->eoe_slaves, list) { ec_eoe_run(eoe); } +#endif + + queue_delayed_work(master->eoe_wq, &master->eoe_work, HZ); } /****************************************************************************** @@ -1298,9 +1300,6 @@ void ecrt_master_run(ec_master_t *master /**< EtherCAT master */) // watchdog command ec_master_process_watch_command(master); ec_master_queue_command(master, &master->watch_command); - - // Ethernet-over-EtherCAT - ec_master_run_eoe(master); } /*****************************************************************************/ @@ -1431,6 +1430,56 @@ void ecrt_master_callbacks(ec_master_t *master, /**< EtherCAT master */ /*****************************************************************************/ +/** + Starts Ethernet-over-EtherCAT processing for all EoE-capable slaves. + \ingroup RealtimeInterface +*/ + +int ecrt_master_start_eoe(ec_master_t *master /**< EtherCAT master */) +{ + ec_eoe_t *eoe; + ec_slave_t *slave; + + if (!master->request_cb || !master->release_cb) { + EC_ERR("EoE requires master callbacks to be set!\n"); + return -1; + } + + list_for_each_entry(slave, &master->slaves, list) { + // does the slave support EoE? + if (!(slave->sii_mailbox_protocols & EC_MBOX_EOE)) continue; + + if (!(eoe = (ec_eoe_t *) kmalloc(sizeof(ec_eoe_t), GFP_KERNEL))) { + EC_ERR("Failed to allocate EoE-Object.\n"); + return -1; + } + if (ec_eoe_init(eoe, slave)) { + kfree(eoe); + return -1; + } + list_add_tail(&eoe->list, &master->eoe_slaves); + } + + if (list_empty(&master->eoe_slaves)) { + EC_WARN("start_eoe: no EoE-capable slaves present.\n"); + return 0; + } + + // create the EoE workqueue, if necessary + if (!master->eoe_wq) { + if (!(master->eoe_wq = create_singlethread_workqueue("eoework"))) { + EC_ERR("Failed to create EoE workqueue!\n"); + return -1; + } + } + + // start EoE processing + queue_work(master->eoe_wq, &master->eoe_work); + return 0; +} + +/*****************************************************************************/ + /** Sets the debug level of the master. The following levels are valid: @@ -1495,6 +1544,8 @@ EXPORT_SYMBOL(ecrt_master_sync_io); EXPORT_SYMBOL(ecrt_master_async_send); EXPORT_SYMBOL(ecrt_master_async_receive); EXPORT_SYMBOL(ecrt_master_run); +EXPORT_SYMBOL(ecrt_master_callbacks); +EXPORT_SYMBOL(ecrt_master_start_eoe); EXPORT_SYMBOL(ecrt_master_debug); EXPORT_SYMBOL(ecrt_master_print); EXPORT_SYMBOL(ecrt_master_get_slave); diff --git a/master/master.h b/master/master.h index e036d3b5..f9f4532a 100644 --- a/master/master.h +++ b/master/master.h @@ -101,6 +101,8 @@ struct ec_master int (*request_cb)(void *); /**< lock request callback */ void (*release_cb)(void *); /**< lock release callback */ void *cb_data; /**< data parameter of locking callbacks */ + struct workqueue_struct *eoe_wq; /**< work queue for EoE processing */ + struct work_struct eoe_work; /**< EoE work object */ }; /*****************************************************************************/ @@ -124,7 +126,6 @@ int ec_master_bus_scan(ec_master_t *); // misc. void ec_master_output_stats(ec_master_t *); -void ec_master_run_eoe(ec_master_t *); /*****************************************************************************/ diff --git a/mini/mini.c b/mini/mini.c index 7ccf06a8..67cc2da5 100644 --- a/mini/mini.c +++ b/mini/mini.c @@ -99,6 +99,19 @@ void run(unsigned long data) /*****************************************************************************/ +int request_lock(void *data) +{ + return 0; +} + +/*****************************************************************************/ + +void release_lock(void *data) +{ +} + +/*****************************************************************************/ + int __init init_mini_module(void) { printk(KERN_INFO "=== Starting Minimal EtherCAT environment... ===\n"); @@ -108,6 +121,8 @@ int __init init_mini_module(void) goto out_return; } + ecrt_master_callbacks(master, request_lock, release_lock, NULL); + printk(KERN_INFO "Registering domain...\n"); if (!(domain1 = ecrt_master_create_domain(master))) { @@ -137,6 +152,12 @@ int __init init_mini_module(void) ecrt_master_print(master, 0); #endif +#if 1 + if (ecrt_master_start_eoe(master)) { + printk(KERN_ERR "Failed to start EoE processing!\n"); + goto out_deactivate; + } +#endif #if 0 if (!(slave = ecrt_master_get_slave(master, "5"))) { @@ -180,7 +201,7 @@ int __init init_mini_module(void) printk(KERN_INFO "=== Minimal EtherCAT environment started. ===\n"); return 0; -#if 0 +#if 1 out_deactivate: ecrt_master_deactivate(master); #endif diff --git a/rt/msr_rt.c b/rt/msr_rt.c index b69acfae..d2fe6967 100644 --- a/rt/msr_rt.c +++ b/rt/msr_rt.c @@ -179,6 +179,13 @@ int __init init_rt_module(void) goto out_release_master; } +#if 0 + if (ecrt_master_start_eoe(master)) { + printk(KERN_ERR "Failed to start EoE processing!\n"); + goto out_deactivate; + } +#endif + #if 0 if (ecrt_master_fetch_sdo_lists(master)) { printk(KERN_ERR "Failed to fetch SDO lists!\n"); -- GitLab