ecrt_master_callbacks: replaced send/receive callback mechanism with locking mechanism; removed ecrt_master_send_ext
authorMartin Troxler <ch1010277@ch10pc446>
Thu, 16 Dec 2010 15:47:28 +0100
changeset 2024 96e2ae6cce95
parent 2023 da133ec36c3a
child 2025 2d7e29d82e9a
ecrt_master_callbacks: replaced send/receive callback mechanism with locking mechanism; removed ecrt_master_send_ext
examples/dc_rtai/dc_rtai_sample.c
examples/mini/mini.c
examples/rtai/rtai_sample.c
examples/tty/tty.c
include/ecrt.h
master/cdev.c
master/master.c
master/master.h
--- a/examples/dc_rtai/dc_rtai_sample.c	Thu Dec 16 12:41:16 2010 +0100
+++ b/examples/dc_rtai/dc_rtai_sample.c	Thu Dec 16 15:47:28 2010 +0100
@@ -229,8 +229,8 @@
         }
         ecrt_master_sync_slave_clocks(master);
         ecrt_domain_queue(domain1);
+        rt_sem_signal(&master_sem);
         ecrt_master_send(master);
-        rt_sem_signal(&master_sem);
 
         rt_task_wait_period();
     }
@@ -238,30 +238,18 @@
 
 /*****************************************************************************/
 
-void send_callback(void *cb_data)
+void request_lock_callback(void *cb_data)
 {
     ec_master_t *m = (ec_master_t *) cb_data;
-
-    // too close to the next real time cycle: deny access...
-    if (get_cycles() - t_last_cycle <= t_critical) {
-        rt_sem_wait(&master_sem);
-        ecrt_master_send_ext(m);
-        rt_sem_signal(&master_sem);
-    }
-}
-
-/*****************************************************************************/
-
-void receive_callback(void *cb_data)
+    rt_sem_wait(&master_sem);
+}
+
+/*****************************************************************************/
+
+void release_lock_callback(void *cb_data)
 {
     ec_master_t *m = (ec_master_t *) cb_data;
-
-    // too close to the next real time cycle: deny access...
-    if (get_cycles() - t_last_cycle <= t_critical) {
-        rt_sem_wait(&master_sem);
-        ecrt_master_receive(m);
-        rt_sem_signal(&master_sem);
-    }
+    rt_sem_signal(&master_sem);
 }
 
 /*****************************************************************************/
@@ -285,7 +273,7 @@
         goto out_return;
     }
 
-    ecrt_master_callbacks(master, send_callback, receive_callback, master);
+    ecrt_master_callbacks(master, request_lock_callback, release_lock_callback, master);
 
     printk(KERN_INFO PFX "Registering domain...\n");
     if (!(domain1 = ecrt_master_create_domain(master))) {
--- a/examples/mini/mini.c	Thu Dec 16 12:41:16 2010 +0100
+++ b/examples/mini/mini.c	Thu Dec 16 15:47:28 2010 +0100
@@ -346,10 +346,9 @@
     EC_WRITE_U8(domain1_pd + off_dig_out, blink ? 0x06 : 0x09);
 
     // send process data
-    down(&master_sem);
     ecrt_domain_queue(domain1);
+    up(&master_sem);
     ecrt_master_send(master);
-    up(&master_sem);
 
     // restart timer
     timer.expires += HZ / FREQUENCY;
@@ -358,21 +357,17 @@
 
 /*****************************************************************************/
 
-void send_callback(void *cb_data)
+void request_lock_callback(void *cb_data)
 {
     ec_master_t *m = (ec_master_t *) cb_data;
     down(&master_sem);
-    ecrt_master_send_ext(m);
-    up(&master_sem);
-}
-
-/*****************************************************************************/
-
-void receive_callback(void *cb_data)
+}
+
+/*****************************************************************************/
+
+void release_lock_callback(void *cb_data)
 {
     ec_master_t *m = (ec_master_t *) cb_data;
-    down(&master_sem);
-    ecrt_master_receive(m);
     up(&master_sem);
 }
 
@@ -398,7 +393,7 @@
     }
 
     sema_init(&master_sem, 1);
-    ecrt_master_callbacks(master, send_callback, receive_callback, master);
+    ecrt_master_callbacks(master, request_lock_callback, release_lock_callback, master);
 
     printk(KERN_INFO PFX "Registering domain...\n");
     if (!(domain1 = ecrt_master_create_domain(master))) {
--- a/examples/rtai/rtai_sample.c	Thu Dec 16 12:41:16 2010 +0100
+++ b/examples/rtai/rtai_sample.c	Thu Dec 16 15:47:28 2010 +0100
@@ -234,8 +234,8 @@
 
         rt_sem_wait(&master_sem);
         ecrt_domain_queue(domain1);
+        rt_sem_signal(&master_sem);
         ecrt_master_send(master);
-        rt_sem_signal(&master_sem);
 
         rt_task_wait_period();
     }
@@ -243,30 +243,18 @@
 
 /*****************************************************************************/
 
-void send_callback(void *cb_data)
+void request_lock_callback(void *cb_data)
 {
     ec_master_t *m = (ec_master_t *) cb_data;
-
-    // too close to the next real time cycle: deny access...
-    if (get_cycles() - t_last_cycle <= t_critical) {
-        rt_sem_wait(&master_sem);
-        ecrt_master_send_ext(m);
-        rt_sem_signal(&master_sem);
-    }
-}
-
-/*****************************************************************************/
-
-void receive_callback(void *cb_data)
+    rt_sem_wait(&master_sem);
+}
+
+/*****************************************************************************/
+
+void release_lock_callback(void *cb_data)
 {
     ec_master_t *m = (ec_master_t *) cb_data;
-
-    // too close to the next real time cycle: deny access...
-    if (get_cycles() - t_last_cycle <= t_critical) {
-        rt_sem_wait(&master_sem);
-        ecrt_master_receive(m);
-        rt_sem_signal(&master_sem);
-    }
+    rt_sem_signal(&master_sem);
 }
 
 /*****************************************************************************/
@@ -292,7 +280,7 @@
         goto out_return;
     }
 
-    ecrt_master_callbacks(master, send_callback, receive_callback, master);
+    ecrt_master_callbacks(master, request_lock_callback, release_lock_callback, master);
 
     printk(KERN_INFO PFX "Registering domain...\n");
     if (!(domain1 = ecrt_master_create_domain(master))) {
--- a/examples/tty/tty.c	Thu Dec 16 12:41:16 2010 +0100
+++ b/examples/tty/tty.c	Thu Dec 16 15:47:28 2010 +0100
@@ -141,8 +141,8 @@
     // send process data
     down(&master_sem);
     ecrt_domain_queue(domain1);
+    up(&master_sem);
     ecrt_master_send(master);
-    up(&master_sem);
 
     // restart timer
     timer.expires += HZ / FREQUENCY;
@@ -151,21 +151,17 @@
 
 /*****************************************************************************/
 
-void send_callback(void *cb_data)
+void request_lock_callback(void *cb_data)
 {
     ec_master_t *m = (ec_master_t *) cb_data;
     down(&master_sem);
-    ecrt_master_send_ext(m);
-    up(&master_sem);
-}
-
-/*****************************************************************************/
-
-void receive_callback(void *cb_data)
+}
+
+/*****************************************************************************/
+
+void release_lock_callback(void *cb_data)
 {
     ec_master_t *m = (ec_master_t *) cb_data;
-    down(&master_sem);
-    ecrt_master_receive(m);
     up(&master_sem);
 }
 
@@ -186,7 +182,7 @@
     }
 
     sema_init(&master_sem, 1);
-    ecrt_master_callbacks(master, send_callback, receive_callback, master);
+    ecrt_master_callbacks(master, request_lock_callback, release_lock_callback, master);
 
     printk(KERN_INFO PFX "Registering domain...\n");
     if (!(domain1 = ecrt_master_create_domain(master))) {
--- a/include/ecrt.h	Thu Dec 16 12:41:16 2010 +0100
+++ b/include/ecrt.h	Thu Dec 16 15:47:28 2010 +0100
@@ -49,9 +49,7 @@
  *   ecrt_master_sync_monitor_queue() and ecrt_master_sync_monitor_process()
  *   methods can be used to monitor the synchrony.
  * - Improved the callback mechanism. ecrt_master_callbacks() now takes two
- *   callback functions for sending and receiving datagrams.
- *   ecrt_master_send_ext() is used to execute the sending of non-application
- *   datagrams.
+ *   callback functions for locking and unlocking the fsm datagram queue.
  * - Added watchdog configuration (method ecrt_slave_config_watchdog(),
  *   #ec_watchdog_mode_t, \a watchdog_mode parameter in ec_sync_info_t and
  *   ecrt_slave_config_sync_manager()).
@@ -512,27 +510,18 @@
 
 /** Sets the locking callbacks.
  *
- * For concurrent master access, i. e. if other instances than the application
- * want to send and receive datagrams on the bus, the application has to
- * provide a callback mechanism. This method takes two function pointers as
- * its parameters. Asynchronous master access (like EoE processing) is only
- * possible if the callbacks have been set.
- *
- * The task of the send callback (\a send_cb) is to decide, if the bus is
- * currently accessible and whether or not to call the ecrt_master_send_ext()
- * method.
- *
- * The task of the receive callback (\a receive_cb) is to decide, if a call to
- * ecrt_master_receive() is allowed and to execute it respectively.
+ * For concurrent master access, the application has to provide a locking
+ * mechanism. The method takes two function pointers and a data value as
+ * its parameters.
+ * The arbitrary \a cb_data value will be passed as argument on every callback.
+ *
  */
 void ecrt_master_callbacks(
         ec_master_t *master, /**< EtherCAT master */
-        void (*send_cb)(void *), /**< Datagram sending callback. */
-        void (*receive_cb)(void *), /**< Receive callback. */
-        void *cb_data /**< Arbitraty pointer passed to the callback functions.
-                       */
-        );
-
+        void (*lock_cb)(void *), /**< Lock function. */
+        void (*unlock_cb)(void *), /**< Unlock function. */
+        void *cb_data /**< Arbitrary user data. */
+        );
 #endif /* __KERNEL__ */
 
 /** Creates a new process data domain.
@@ -817,15 +806,6 @@
         ec_master_t *master /**< EtherCAT master. */
         );
 
-/** Sends non-application datagrams.
- *
- * This method has to be called in the send callback function passed via
- * ecrt_master_callbacks() to allow the sending of non-application datagrams.
- */
-void ecrt_master_send_ext(
-        ec_master_t *master /**< EtherCAT master. */
-        );
-
 /** Reads the current master state.
  *
  * Stores the master state information in the given \a state structure.
--- a/master/cdev.c	Thu Dec 16 12:41:16 2010 +0100
+++ b/master/cdev.c	Thu Dec 16 15:47:28 2010 +0100
@@ -1769,9 +1769,6 @@
         }
     }
 
-    ecrt_master_callbacks(master, ec_master_internal_send_cb,
-            ec_master_internal_receive_cb, master);
-
     ret = ecrt_master_activate(master);
     if (ret < 0)
         return ret;
--- a/master/master.c	Thu Dec 16 12:41:16 2010 +0100
+++ b/master/master.c	Thu Dec 16 15:47:28 2010 +0100
@@ -191,12 +191,12 @@
 #endif
 
     sema_init(&master->io_sem, 1);
-    master->send_cb = NULL;
-    master->receive_cb = NULL;
-    master->cb_data = NULL;
-    master->app_send_cb = NULL;
-    master->app_receive_cb = NULL;
-    master->app_cb_data = NULL;
+    master->fsm_queue_lock_cb = NULL;
+    master->fsm_queue_unlock_cb = NULL;
+    master->fsm_queue_locking_data = NULL;
+    master->app_fsm_queue_lock_cb = NULL;
+    master->app_fsm_queue_unlock_cb = NULL;
+    master->app_fsm_queue_locking_data = NULL;
 
     INIT_LIST_HEAD(&master->sii_requests);
     init_waitqueue_head(&master->sii_queue);
@@ -455,34 +455,6 @@
 
 /*****************************************************************************/
 
-/** Internal sending callback.
- */
-void ec_master_internal_send_cb(
-        void *cb_data /**< Callback data. */
-        )
-{
-    ec_master_t *master = (ec_master_t *) cb_data;
-    down(&master->io_sem);
-    ecrt_master_send_ext(master);
-    up(&master->io_sem);
-}
-
-/*****************************************************************************/
-
-/** Internal receiving callback.
- */
-void ec_master_internal_receive_cb(
-        void *cb_data /**< Callback data. */
-        )
-{
-    ec_master_t *master = (ec_master_t *) cb_data;
-    down(&master->io_sem);
-    ecrt_master_receive(master);
-    up(&master->io_sem);
-}
-
-/*****************************************************************************/
-
 /** Starts the master thread.
  *
  * \retval  0 Success.
@@ -548,9 +520,9 @@
 
     EC_MASTER_DBG(master, 1, "ORPHANED -> IDLE.\n");
 
-    master->send_cb = ec_master_internal_send_cb;
-    master->receive_cb = ec_master_internal_receive_cb;
-    master->cb_data = master;
+    master->fsm_queue_lock_cb = NULL;
+    master->fsm_queue_unlock_cb = NULL;
+    master->fsm_queue_locking_data = NULL;
 
     master->phase = EC_IDLE;
     ret = ec_master_thread_start(master, ec_master_idle_thread,
@@ -647,9 +619,9 @@
 #endif
 
     master->phase = EC_OPERATION;
-    master->app_send_cb = NULL;
-    master->app_receive_cb = NULL;
-    master->app_cb_data = NULL;
+    master->app_fsm_queue_lock_cb = NULL;
+    master->app_fsm_queue_unlock_cb = NULL;
+    master->app_fsm_queue_locking_data = NULL;
     return ret;
     
 out_allow:
@@ -688,9 +660,13 @@
     ec_datagram_t *datagram, *n;
     size_t queue_size = 0;
 
+    if (master->fsm_queue_lock_cb)
+        master->fsm_queue_lock_cb(master->fsm_queue_locking_data);
     down(&master->fsm_queue_sem);
     if (list_empty(&master->fsm_datagram_queue)) {
         up(&master->fsm_queue_sem);
+        if (master->fsm_queue_unlock_cb)
+            master->fsm_queue_unlock_cb(master->fsm_queue_locking_data);
         return;
     }
     list_for_each_entry(datagram, &master->datagram_queue, queue) {
@@ -761,6 +737,8 @@
         }
     }
     up(&master->fsm_queue_sem);
+    if (master->fsm_queue_unlock_cb)
+        master->fsm_queue_unlock_cb(master->fsm_queue_locking_data);
 }
 
 /*****************************************************************************/
@@ -803,6 +781,8 @@
 {
     ec_datagram_t *queued_datagram;
 
+    if (master->fsm_queue_lock_cb)
+        master->fsm_queue_lock_cb(master->fsm_queue_locking_data);
     down(&master->fsm_queue_sem);
 
     // check, if the datagram is already queued
@@ -811,6 +791,8 @@
         if (queued_datagram == datagram) {
             datagram->state = EC_DATAGRAM_QUEUED;
             up(&master->fsm_queue_sem);
+            if (master->fsm_queue_unlock_cb)
+                master->fsm_queue_unlock_cb(master->fsm_queue_locking_data);
             return;
         }
     }
@@ -828,6 +810,8 @@
     datagram->jiffies_sent = jiffies;
 
     up(&master->fsm_queue_sem);
+    if (master->fsm_queue_unlock_cb)
+        master->fsm_queue_unlock_cb(master->fsm_queue_locking_data);
 }
 
 /*****************************************************************************/
@@ -1943,9 +1927,9 @@
     master->injection_seq_fsm = 0;
     master->injection_seq_rt = 0;
 
-    master->send_cb = master->app_send_cb;
-    master->receive_cb = master->app_receive_cb;
-    master->cb_data = master->app_cb_data;
+    master->fsm_queue_lock_cb = master->app_fsm_queue_lock_cb;
+    master->fsm_queue_unlock_cb = master->app_fsm_queue_unlock_cb;
+    master->fsm_queue_locking_data = master->app_fsm_queue_locking_data;
     
     ret = ec_master_thread_start(master, ec_master_operation_thread,
                 "EtherCAT-OP");
@@ -1982,9 +1966,9 @@
 
     ec_master_thread_stop(master);
     
-    master->send_cb = ec_master_internal_send_cb;
-    master->receive_cb = ec_master_internal_receive_cb;
-    master->cb_data = master;
+    master->fsm_queue_lock_cb = NULL;
+    master->fsm_queue_unlock_cb= NULL;
+    master->fsm_queue_locking_data = NULL;
     
     ec_master_clear_config(master);
 
@@ -2096,12 +2080,6 @@
     }
 }
 
-/*****************************************************************************/
-
-void ecrt_master_send_ext(ec_master_t *master)
-{
-    ecrt_master_send(master);
-}
 
 /*****************************************************************************/
 
@@ -2226,16 +2204,18 @@
 /*****************************************************************************/
 
 void ecrt_master_callbacks(ec_master_t *master,
-        void (*send_cb)(void *), void (*receive_cb)(void *), void *cb_data)
-{
-    EC_MASTER_DBG(master, 1, "ecrt_master_callbacks(master = 0x%p,"
-            " send_cb = 0x%p, receive_cb = 0x%p, cb_data = 0x%p)\n",
-            master, send_cb, receive_cb, cb_data);
-
-    master->app_send_cb = send_cb;
-    master->app_receive_cb = receive_cb;
-    master->app_cb_data = cb_data;
-}
+                           void (*lock_cb)(void *), void (*unlock_cb)(void *),
+                           void *cb_data)
+{
+    EC_MASTER_DBG(master, 1,"ecrt_master_callbacks(master = %p, "
+                            "lock_cb = %p, unlock_cb = %p, cb_data = %p)\n",
+                            master, lock_cb, unlock_cb, cb_data);
+
+    master->app_fsm_queue_lock_cb = lock_cb;
+    master->app_fsm_queue_unlock_cb = unlock_cb;
+    master->app_fsm_queue_locking_data = cb_data;
+}
+
 
 /*****************************************************************************/
 
@@ -2482,7 +2462,6 @@
 EXPORT_SYMBOL(ecrt_master_activate);
 EXPORT_SYMBOL(ecrt_master_deactivate);
 EXPORT_SYMBOL(ecrt_master_send);
-EXPORT_SYMBOL(ecrt_master_send_ext);
 EXPORT_SYMBOL(ecrt_master_receive);
 EXPORT_SYMBOL(ecrt_master_callbacks);
 EXPORT_SYMBOL(ecrt_master);
--- a/master/master.h	Thu Dec 16 12:41:16 2010 +0100
+++ b/master/master.h	Thu Dec 16 15:47:28 2010 +0100
@@ -229,14 +229,12 @@
 
     struct semaphore io_sem; /**< Semaphore used in \a IDLE phase. */
 
-    void (*send_cb)(void *); /**< Current send datagrams callback. */
-    void (*receive_cb)(void *); /**< Current receive datagrams callback. */
-    void *cb_data; /**< Current callback data. */
-    void (*app_send_cb)(void *); /**< Application's send datagrams
-                                          callback. */
-    void (*app_receive_cb)(void *); /**< Application's receive datagrams
-                                      callback. */
-    void *app_cb_data; /**< Application callback data. */
+    void (*fsm_queue_lock_cb)(void *); /**< FSM queue lock callback. */
+    void (*fsm_queue_unlock_cb)(void *); /**< FSM queue unlock callback. */
+    void *fsm_queue_locking_data; /**< Data parameter of fsm queue locking callbacks. */
+    void (*app_fsm_queue_lock_cb)(void *); /**< App's FSM queue lock callback. */
+    void (*app_fsm_queue_unlock_cb)(void *); /**< App's FSM queue unlock callback. */
+    void *app_fsm_queue_locking_data; /**< App's data parameter of fsm queue locking callbacks. */
 
     struct list_head sii_requests; /**< SII write requests. */
     wait_queue_head_t sii_queue; /**< Wait queue for SII
@@ -304,9 +302,6 @@
 void ec_master_calc_dc(ec_master_t *);
 void ec_master_request_op(ec_master_t *);
 
-void ec_master_internal_send_cb(void *);
-void ec_master_internal_receive_cb(void *);
-
-/*****************************************************************************/
-
-#endif
+/*****************************************************************************/
+
+#endif