Prepared EoE processing with workqueue.
authorFlorian Pose <fp@igh-essen.com>
Tue, 25 Apr 2006 13:43:13 +0000
changeset 206 60a10d85c20b
parent 205 7fa6de7e3823
child 207 3e0a148eb38d
Prepared EoE processing with workqueue.
include/ecrt.h
master/master.c
master/master.h
mini/mini.c
rt/msr_rt.c
--- a/include/ecrt.h	Tue Apr 25 12:15:54 2006 +0000
+++ b/include/ecrt.h	Tue Apr 25 13:43:13 2006 +0000
@@ -105,6 +105,8 @@
 
 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);
 
--- a/master/master.c	Tue Apr 25 12:15:54 2006 +0000
+++ b/master/master.c	Tue Apr 25 13:43:13 2006 +0000
@@ -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 @@
     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 @@
     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 @@
     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 @@
     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 @@
         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 @@
    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 @@
     // watchdog command
     ec_master_process_watch_command(master);
     ec_master_queue_command(master, &master->watch_command);
-
-    // Ethernet-over-EtherCAT
-    ec_master_run_eoe(master);
 }
 
 /*****************************************************************************/
@@ -1432,6 +1431,56 @@
 /*****************************************************************************/
 
 /**
+   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:
    - 1: only output positions marks and basic data
@@ -1495,6 +1544,8 @@
 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);
--- a/master/master.h	Tue Apr 25 12:15:54 2006 +0000
+++ b/master/master.h	Tue Apr 25 13:43:13 2006 +0000
@@ -101,6 +101,8 @@
     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 @@
 
 // misc.
 void ec_master_output_stats(ec_master_t *);
-void ec_master_run_eoe(ec_master_t *);
 
 /*****************************************************************************/
 
--- a/mini/mini.c	Tue Apr 25 12:15:54 2006 +0000
+++ b/mini/mini.c	Tue Apr 25 13:43:13 2006 +0000
@@ -99,6 +99,19 @@
 
 /*****************************************************************************/
 
+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 @@
         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 @@
     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 @@
     printk(KERN_INFO "=== Minimal EtherCAT environment started. ===\n");
     return 0;
 
-#if 0
+#if 1
  out_deactivate:
     ecrt_master_deactivate(master);
 #endif
--- a/rt/msr_rt.c	Tue Apr 25 12:15:54 2006 +0000
+++ b/rt/msr_rt.c	Tue Apr 25 13:43:13 2006 +0000
@@ -180,6 +180,13 @@
     }
 
 #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");
         goto out_deactivate;