Improved the callback mechanism.
--- a/NEWS Fri Jul 10 10:40:05 2009 +0000
+++ b/NEWS Mon Jul 13 15:18:28 2009 +0000
@@ -12,6 +12,10 @@
library is licensed under LGPLv2.
* Added distributed clocks support.
* Added VoE mailbox protocol support.
+* 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.
* Separated datagram initialization from filling the payload with zeros.
Introduced new method ec_datagram_zero() for that.
* Added phy_read and phy_write commands to ethercat tool.
--- a/TODO Fri Jul 10 10:40:05 2009 +0000
+++ b/TODO Mon Jul 13 15:18:28 2009 +0000
@@ -24,8 +24,6 @@
* Remove byte-swapping functions from user space.
* EoE:
- Only execute one EoE handler per cycle.
- - Replace locking callbacks.
- - Allow EoE with userspace application.
* Implement 'ethercat foe_read --output-file ...'.
* Fix unloading problem of ec_e100 driver.
* Use ec_datagram_zero() where possible.
@@ -41,7 +39,6 @@
* Remove ecrt_domain_state()?
* Check force_config flag before error.
* Remove allow_scanning flag.
-* Implement ecrt_master_slave() in kernel space.
* Check for ioctl() interface version.
* Improve application-triggered SDO transfers by moving the state machine into
the SDO handlers.
--- a/examples/dc_rtai/dc_rtai_sample.c Fri Jul 10 10:40:05 2009 +0000
+++ b/examples/dc_rtai/dc_rtai_sample.c Mon Jul 13 15:18:28 2009 +0000
@@ -58,7 +58,6 @@
// EtherCAT
static ec_master_t *master = NULL;
static ec_master_state_t master_state = {};
-spinlock_t master_lock = SPIN_LOCK_UNLOCKED;
static ec_domain_t *domain1 = NULL;
static ec_domain_state_t domain1_state = {};
@@ -125,9 +124,9 @@
{
ec_domain_state_t ds;
- spin_lock(&master_lock);
+ rt_sem_wait(&master_sem);
ecrt_domain_state(domain1, &ds);
- spin_unlock(&master_lock);
+ rt_sem_signal(&master_sem);
if (ds.working_counter != domain1_state.working_counter)
printk(KERN_INFO PFX "Domain1: WC %u.\n", ds.working_counter);
@@ -143,9 +142,9 @@
{
ec_master_state_t ms;
- spin_lock(&master_lock);
+ rt_sem_wait(&master_sem);
ecrt_master_state(master, &ms);
- spin_unlock(&master_lock);
+ rt_sem_signal(&master_sem);
if (ms.slaves_responding != master_state.slaves_responding)
printk(KERN_INFO PFX "%u slave(s).\n", ms.slaves_responding);
@@ -239,21 +238,26 @@
/*****************************************************************************/
-int request_lock(void *data)
+void send_callback(ec_master_t *master)
{
// too close to the next real time cycle: deny access...
- if (get_cycles() - t_last_cycle > t_critical) return -1;
-
- // allow access
- rt_sem_wait(&master_sem);
- return 0;
-}
-
-/*****************************************************************************/
-
-void release_lock(void *data)
-{
- rt_sem_signal(&master_sem);
+ if (get_cycles() - t_last_cycle <= t_critical) {
+ rt_sem_wait(&master_sem);
+ ecrt_master_send_ext(master);
+ rt_sem_signal(&master_sem);
+ }
+}
+
+/*****************************************************************************/
+
+void receive_callback(ec_master_t *master)
+{
+ // 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(master);
+ rt_sem_signal(&master_sem);
+ }
}
/*****************************************************************************/
@@ -277,7 +281,7 @@
goto out_return;
}
- ecrt_master_callbacks(master, request_lock, release_lock, NULL);
+ ecrt_master_callbacks(master, send_callback, receive_callback);
printk(KERN_INFO PFX "Registering domain...\n");
if (!(domain1 = ecrt_master_create_domain(master))) {
--- a/examples/mini/mini.c Fri Jul 10 10:40:05 2009 +0000
+++ b/examples/mini/mini.c Mon Jul 13 15:18:28 2009 +0000
@@ -29,7 +29,7 @@
#include <linux/module.h>
#include <linux/timer.h>
-#include <linux/spinlock.h>
+#include <linux/semaphore.h>
#include <linux/interrupt.h>
#include <linux/err.h>
@@ -54,7 +54,7 @@
// EtherCAT
static ec_master_t *master = NULL;
static ec_master_state_t master_state = {};
-spinlock_t master_lock = SPIN_LOCK_UNLOCKED;
+struct semaphore master_sem;
static ec_domain_t *domain1 = NULL;
static ec_domain_state_t domain1_state = {};
@@ -192,9 +192,9 @@
{
ec_domain_state_t ds;
- spin_lock(&master_lock);
+ down(&master_sem);
ecrt_domain_state(domain1, &ds);
- spin_unlock(&master_lock);
+ up(&master_sem);
if (ds.working_counter != domain1_state.working_counter)
printk(KERN_INFO PFX "Domain1: WC %u.\n", ds.working_counter);
@@ -210,9 +210,9 @@
{
ec_master_state_t ms;
- spin_lock(&master_lock);
+ down(&master_sem);
ecrt_master_state(master, &ms);
- spin_unlock(&master_lock);
+ up(&master_sem);
if (ms.slaves_responding != master_state.slaves_responding)
printk(KERN_INFO PFX "%u slave(s).\n", ms.slaves_responding);
@@ -230,9 +230,9 @@
{
ec_slave_config_state_t s;
- spin_lock(&master_lock);
+ down(&master_sem);
ecrt_slave_config_state(sc_ana_in, &s);
- spin_unlock(&master_lock);
+ up(&master_sem);
if (s.al_state != sc_ana_in_state.al_state)
printk(KERN_INFO PFX "AnaIn: State 0x%02X.\n", s.al_state);
@@ -300,10 +300,10 @@
void cyclic_task(unsigned long data)
{
// receive process data
- spin_lock(&master_lock);
+ down(&master_sem);
ecrt_master_receive(master);
ecrt_domain_process(domain1);
- spin_unlock(&master_lock);
+ up(&master_sem);
// check process data state (optional)
check_domain1_state();
@@ -336,10 +336,10 @@
EC_WRITE_U8(domain1_pd + off_dig_out, blink ? 0x06 : 0x09);
// send process data
- spin_lock(&master_lock);
+ down(&master_sem);
ecrt_domain_queue(domain1);
ecrt_master_send(master);
- spin_unlock(&master_lock);
+ up(&master_sem);
// restart timer
timer.expires += HZ / FREQUENCY;
@@ -348,17 +348,20 @@
/*****************************************************************************/
-int request_lock(void *data)
-{
- spin_lock(&master_lock);
- return 0; // access allowed
-}
-
-/*****************************************************************************/
-
-void release_lock(void *data)
-{
- spin_unlock(&master_lock);
+void send_callback(ec_master_t *master)
+{
+ down(&master_sem);
+ ecrt_master_send_ext(master);
+ up(&master_sem);
+}
+
+/*****************************************************************************/
+
+void receive_callback(ec_master_t *master)
+{
+ down(&master_sem);
+ ecrt_master_receive(master);
+ up(&master_sem);
}
/*****************************************************************************/
@@ -382,7 +385,8 @@
goto out_return;
}
- ecrt_master_callbacks(master, request_lock, release_lock, NULL);
+ init_MUTEX(&master_sem);
+ ecrt_master_callbacks(master, send_callback, receive_callback);
printk(KERN_INFO PFX "Registering domain...\n");
if (!(domain1 = ecrt_master_create_domain(master))) {
--- a/examples/rtai/rtai_sample.c Fri Jul 10 10:40:05 2009 +0000
+++ b/examples/rtai/rtai_sample.c Mon Jul 13 15:18:28 2009 +0000
@@ -59,7 +59,6 @@
// EtherCAT
static ec_master_t *master = NULL;
static ec_master_state_t master_state = {};
-spinlock_t master_lock = SPIN_LOCK_UNLOCKED;
static ec_domain_t *domain1 = NULL;
static ec_domain_state_t domain1_state = {};
@@ -146,9 +145,9 @@
{
ec_domain_state_t ds;
- spin_lock(&master_lock);
+ rt_sem_wait(&master_sem);
ecrt_domain_state(domain1, &ds);
- spin_unlock(&master_lock);
+ rt_sem_signal(&master_sem);
if (ds.working_counter != domain1_state.working_counter)
printk(KERN_INFO PFX "Domain1: WC %u.\n", ds.working_counter);
@@ -164,9 +163,9 @@
{
ec_master_state_t ms;
- spin_lock(&master_lock);
+ rt_sem_wait(&master_sem);
ecrt_master_state(master, &ms);
- spin_unlock(&master_lock);
+ rt_sem_signal(&master_sem);
if (ms.slaves_responding != master_state.slaves_responding)
printk(KERN_INFO PFX "%u slave(s).\n", ms.slaves_responding);
@@ -184,9 +183,9 @@
{
ec_slave_config_state_t s;
- spin_lock(&master_lock);
+ rt_sem_wait(&master_sem);
ecrt_slave_config_state(sc_ana_in, &s);
- spin_unlock(&master_lock);
+ rt_sem_signal(&master_sem);
if (s.al_state != sc_ana_in_state.al_state)
printk(KERN_INFO PFX "AnaIn: State 0x%02X.\n", s.al_state);
@@ -244,21 +243,26 @@
/*****************************************************************************/
-int request_lock(void *data)
+void send_callback(ec_master_t *master)
{
// too close to the next real time cycle: deny access...
- if (get_cycles() - t_last_cycle > t_critical) return -1;
-
- // allow access
- rt_sem_wait(&master_sem);
- return 0;
-}
-
-/*****************************************************************************/
-
-void release_lock(void *data)
-{
- rt_sem_signal(&master_sem);
+ if (get_cycles() - t_last_cycle <= t_critical) {
+ rt_sem_wait(&master_sem);
+ ecrt_master_send_ext(master);
+ rt_sem_signal(&master_sem);
+ }
+}
+
+/*****************************************************************************/
+
+void receive_callback(ec_master_t *master)
+{
+ // 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(master);
+ rt_sem_signal(&master_sem);
+ }
}
/*****************************************************************************/
@@ -277,7 +281,6 @@
t_critical = cpu_khz * 1000 / FREQUENCY - cpu_khz * INHIBIT_TIME / 1000;
-
master = ecrt_request_master(0);
if (IS_ERR(master)) {
ret = PTR_ERR(master);
@@ -285,7 +288,7 @@
goto out_return;
}
- ecrt_master_callbacks(master, request_lock, release_lock, NULL);
+ ecrt_master_callbacks(master, send_callback, receive_callback);
printk(KERN_INFO PFX "Registering domain...\n");
if (!(domain1 = ecrt_master_create_domain(master))) {
--- a/include/ecrt.h Fri Jul 10 10:40:05 2009 +0000
+++ b/include/ecrt.h Mon Jul 13 15:18:28 2009 +0000
@@ -42,24 +42,27 @@
* Changes in version 1.5:
*
* - Added the distributed clocks feature and the respective method
- * ecrt_slave_config_dc() to configure a slave for cyclic
- * operation, and ecrt_master_application_time(),
- * ecrt_master_sync_reference_clock() and ecrt_master_sync_slave_clocks()
- * for offset and drift compensation. The EC_TIMEVAL2NANO() macro can be
- * used for epoch time conversion.
+ * ecrt_slave_config_dc() to configure a slave for cyclic operation, and
+ * ecrt_master_application_time(), ecrt_master_sync_reference_clock() and
+ * ecrt_master_sync_slave_clocks() for offset and drift compensation. The
+ * EC_TIMEVAL2NANO() macro can be used for epoch time conversion.
+ * - 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.
* - Added ecrt_open_master() and ecrt_master_reserve() separation for
* userspace.
* - Added ecrt_master() userspace interface, to get information about a
* master.
+ * - Added ecrt_master_slave() to get information about a certain slave.
+ * - Added ecrt_slave_sdo_upload() and ecrt_slave_sdo_download() methods to
+ * let an application transfer SDOs before activating the master.
* - Changed the meaning of the negative return values of
* ecrt_slave_config_reg_pdo_entry() and ecrt_slave_config_sdo*().
* - Imlemented the Vendor-specific over EtherCAT mailbox protocol. See
* ecrt_slave_config_create_voe_handler().
* - Renamed ec_sdo_request_state_t to ec_request_state_t, because it is also
* used by VoE handlers.
- * - Added ecrt_master_slave() to get information about a certain slave.
- * - Added ecrt_slave_sdo_upload() and ecrt_slave_sdo_download() methods to
- * let an application transfer SDOs before activating the master.
* - Removed 'const' from argument of ecrt_sdo_request_state(), because the
* userspace library has to modify object internals.
* - Added 64-bit data access macros.
@@ -442,21 +445,23 @@
/** Sets the locking callbacks.
*
- * For concurrent master access, the application has to provide a locking
- * mechanism (see section FIXME in the docs). 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. Asynchronous master access
- * (like EoE processing) is only possible if the callbacks have been set.
- *
- * The request_cb function must return zero, to allow another instance
- * (an EoE process for example) to access the master. Non-zero means,
- * that access is currently forbidden.
+ * 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 request_cb) is to decide, if the bus is
+ * currently accessible. In this case, it can 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.
*/
void ecrt_master_callbacks(
ec_master_t *master, /**< EtherCAT master */
- int (*request_cb)(void *), /**< Lock request function. */
- void (*release_cb)(void *), /**< Lock release function. */
- void *cb_data /**< Arbitrary user data. */
+ void (*send_cb)(ec_master_t *), /**< Datagram sending callback. */
+ void (*receive_cb)(ec_master_t *) /**< Receive callback. */
);
#endif /* __KERNEL__ */
@@ -591,6 +596,15 @@
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 Fri Jul 10 10:40:05 2009 +0000
+++ b/master/cdev.c Mon Jul 13 15:18:28 2009 +0000
@@ -1621,6 +1621,9 @@
}
}
+ ecrt_master_callbacks(master, ec_master_internal_send_cb,
+ ec_master_internal_receive_cb);
+
ret = ecrt_master_activate(master);
if (ret < 0)
return ret;
--- a/master/ethernet.c Fri Jul 10 10:40:05 2009 +0000
+++ b/master/ethernet.c Mon Jul 13 15:18:28 2009 +0000
@@ -324,7 +324,7 @@
void ec_eoe_queue(ec_eoe_t *eoe /**< EoE handler */)
{
if (eoe->queue_datagram) {
- ec_master_queue_datagram(eoe->slave->master, &eoe->datagram);
+ ec_master_queue_datagram_ext(eoe->slave->master, &eoe->datagram);
eoe->queue_datagram = 0;
}
}
--- a/master/master.c Fri Jul 10 10:40:05 2009 +0000
+++ b/master/master.c Mon Jul 13 15:18:28 2009 +0000
@@ -146,6 +146,9 @@
INIT_LIST_HEAD(&master->datagram_queue);
master->datagram_index = 0;
+ INIT_LIST_HEAD(&master->ext_datagram_queue);
+ init_MUTEX(&master->ext_queue_sem);
+
INIT_LIST_HEAD(&master->domains);
master->debug_level = debug_level;
@@ -163,9 +166,10 @@
#endif
init_MUTEX(&master->io_sem);
- master->request_cb = NULL;
- master->release_cb = NULL;
- master->cb_data = NULL;
+ master->send_cb = NULL;
+ master->receive_cb = NULL;
+ master->app_send_cb = NULL;
+ master->app_receive_cb = NULL;
INIT_LIST_HEAD(&master->sii_requests);
init_waitqueue_head(&master->sii_queue);
@@ -375,22 +379,27 @@
/*****************************************************************************/
-/** Internal locking callback.
- */
-int ec_master_request_cb(void *data /**< callback data */)
-{
- ec_master_t *master = (ec_master_t *) data;
+/** Internal sending callback.
+ */
+void ec_master_internal_send_cb(
+ ec_master_t *master /**< EtherCAT master. */
+ )
+{
down(&master->io_sem);
- return 0;
-}
-
-/*****************************************************************************/
-
-/** Internal unlocking callback.
- */
-void ec_master_release_cb(void *data /**< callback data */)
-{
- ec_master_t *master = (ec_master_t *) data;
+ ecrt_master_send_ext(master);
+ up(&master->io_sem);
+}
+
+/*****************************************************************************/
+
+/** Internal receiving callback.
+ */
+void ec_master_internal_receive_cb(
+ ec_master_t *master /**< EtherCAT master. */
+ )
+{
+ down(&master->io_sem);
+ ecrt_master_receive(master);
up(&master->io_sem);
}
@@ -462,9 +471,8 @@
if (master->debug_level)
EC_DBG("ORPHANED -> IDLE.\n");
- master->request_cb = ec_master_request_cb;
- master->release_cb = ec_master_release_cb;
- master->cb_data = master;
+ master->send_cb = ec_master_internal_send_cb;
+ master->receive_cb = ec_master_internal_receive_cb;
master->phase = EC_IDLE;
ret = ec_master_thread_start(master, ec_master_idle_thread,
@@ -564,9 +572,8 @@
#endif
master->phase = EC_OPERATION;
- master->ext_request_cb = NULL;
- master->ext_release_cb = NULL;
- master->ext_cb_data = NULL;
+ master->app_send_cb = NULL;
+ master->app_receive_cb = NULL;
return ret;
out_allow:
@@ -597,9 +604,8 @@
#endif
ec_master_thread_stop(master);
- master->request_cb = ec_master_request_cb;
- master->release_cb = ec_master_release_cb;
- master->cb_data = master;
+ master->send_cb = ec_master_internal_send_cb;
+ master->receive_cb = ec_master_internal_receive_cb;
down(&master->master_sem);
ec_master_clear_domains(master);
@@ -646,9 +652,10 @@
/** Places a datagram in the datagram queue.
*/
-void ec_master_queue_datagram(ec_master_t *master, /**< EtherCAT master */
- ec_datagram_t *datagram /**< datagram */
- )
+void ec_master_queue_datagram(
+ ec_master_t *master, /**< EtherCAT master */
+ ec_datagram_t *datagram /**< datagram */
+ )
{
ec_datagram_t *queued_datagram;
@@ -669,6 +676,20 @@
/*****************************************************************************/
+/** Places a datagram in the non-application datagram queue.
+ */
+void ec_master_queue_datagram_ext(
+ ec_master_t *master, /**< EtherCAT master */
+ ec_datagram_t *datagram /**< datagram */
+ )
+{
+ down(&master->ext_queue_sem);
+ list_add_tail(&datagram->queue, &master->ext_datagram_queue);
+ up(&master->ext_queue_sem);
+}
+
+/*****************************************************************************/
+
/** Sends the datagrams in the queue.
*
* \return 0 in case of success, else < 0
@@ -1048,8 +1069,8 @@
if (list_empty(&master->eoe_handlers))
return;
- if (!master->request_cb || !master->release_cb) {
- EC_WARN("No EoE processing because of missing locking callbacks!\n");
+ if (!master->send_cb || !master->receive_cb) {
+ EC_WARN("No EoE processing because of missing callbacks!\n");
return;
}
@@ -1109,11 +1130,7 @@
goto schedule;
// receive datagrams
- if (master->request_cb(master->cb_data))
- goto schedule;
-
- ecrt_master_receive(master);
- master->release_cb(master->cb_data);
+ master->receive_cb(master);
// actual EoE processing
sth_to_send = 0;
@@ -1128,15 +1145,13 @@
}
if (sth_to_send) {
- // send datagrams
- if (master->request_cb(master->cb_data)) {
- goto schedule;
- }
list_for_each_entry(eoe, &master->eoe_handlers, list) {
ec_eoe_queue(eoe);
}
- ecrt_master_send(master);
- master->release_cb(master->cb_data);
+ // (try to) send datagrams
+ down(&master->ext_queue_sem);
+ master->send_cb(master);
+ up(&master->ext_queue_sem);
}
schedule:
@@ -1641,9 +1656,9 @@
master->injection_seq_fsm = 0;
master->injection_seq_rt = 0;
- master->request_cb = master->ext_request_cb;
- master->release_cb = master->ext_release_cb;
- master->cb_data = master->ext_cb_data;
+
+ master->send_cb = master->app_send_cb;
+ master->receive_cb = master->app_receive_cb;
ret = ec_master_thread_start(master, ec_master_operation_thread,
"EtherCAT-OP");
@@ -1735,6 +1750,21 @@
/*****************************************************************************/
+void ecrt_master_send_ext(ec_master_t *master)
+{
+ ec_datagram_t *datagram, *next;
+
+ list_for_each_entry_safe(datagram, next, &master->ext_datagram_queue,
+ queue) {
+ list_del(&datagram->queue);
+ ec_master_queue_datagram(master, datagram);
+ }
+
+ ecrt_master_send(master);
+}
+
+/*****************************************************************************/
+
/** Same as ecrt_master_slave_config(), but with ERR_PTR() return value.
*/
ec_slave_config_t *ecrt_master_slave_config_err(ec_master_t *master,
@@ -1805,17 +1835,16 @@
/*****************************************************************************/
-void ecrt_master_callbacks(ec_master_t *master, int (*request_cb)(void *),
- void (*release_cb)(void *), void *cb_data)
+void ecrt_master_callbacks(ec_master_t *master,
+ void (*send_cb)(ec_master_t *), void (*receive_cb)(ec_master_t *))
{
if (master->debug_level)
- EC_DBG("ecrt_master_callbacks(master = 0x%x, request_cb = 0x%x, "
- " release_cb = 0x%x, cb_data = 0x%x)\n", (u32) master,
- (u32) request_cb, (u32) release_cb, (u32) cb_data);
-
- master->ext_request_cb = request_cb;
- master->ext_release_cb = release_cb;
- master->ext_cb_data = cb_data;
+ EC_DBG("ecrt_master_callbacks(master = 0x%x, send_cb = 0x%x, "
+ " receive_cb = 0x%x)\n", (u32) master, (u32) send_cb,
+ (u32) receive_cb);
+
+ master->app_send_cb = send_cb;
+ master->app_receive_cb = receive_cb;
}
/*****************************************************************************/
@@ -1862,6 +1891,7 @@
EXPORT_SYMBOL(ecrt_master_create_domain);
EXPORT_SYMBOL(ecrt_master_activate);
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_slave_config);
--- a/master/master.h Fri Jul 10 10:40:05 2009 +0000
+++ b/master/master.h Mon Jul 13 15:18:28 2009 +0000
@@ -145,6 +145,11 @@
struct list_head datagram_queue; /**< Datagram queue. */
uint8_t datagram_index; /**< Current datagram index. */
+ struct list_head ext_datagram_queue; /**< Queue for non-application
+ datagrams. */
+ struct semaphore ext_queue_sem; /**< Semaphore protecting the \a
+ ext_datagram_queue. */
+
struct list_head domains; /**< List of domains. */
unsigned int debug_level; /**< Master debug level. */
@@ -160,12 +165,13 @@
#endif
struct semaphore io_sem; /**< Semaphore used in \a IDLE phase. */
- int (*request_cb)(void *); /**< Lock request callback. */
- void (*release_cb)(void *); /**< Lock release callback. */
- void *cb_data; /**< Data parameter of locking callbacks. */
- int (*ext_request_cb)(void *); /**< External lock request callback. */
- void (*ext_release_cb)(void *); /**< External lock release callback. */
- void *ext_cb_data; /**< Data parameter of external locking callbacks. */
+
+ void (*send_cb)(ec_master_t *); /**< Current send datagrams callback. */
+ void (*receive_cb)(ec_master_t *); /**< Current receive datagrams callback. */
+ void (*app_send_cb)(ec_master_t *); /**< Application's send datagrams
+ callback. */
+ void (*app_receive_cb)(ec_master_t *); /**< Application's receive datagrams
+ callback. */
struct list_head sii_requests; /**< SII write requests. */
wait_queue_head_t sii_queue; /**< Wait queue for SII
@@ -208,6 +214,7 @@
// datagram IO
void ec_master_receive_datagrams(ec_master_t *, const uint8_t *, size_t);
void ec_master_queue_datagram(ec_master_t *, ec_datagram_t *);
+void ec_master_queue_datagram_ext(ec_master_t *, ec_datagram_t *);
// misc.
void ec_master_attach_slave_configs(ec_master_t *);
@@ -240,6 +247,9 @@
void ec_master_calc_dc(ec_master_t *);
-/*****************************************************************************/
-
-#endif
+void ec_master_internal_send_cb(ec_master_t *);
+void ec_master_internal_receive_cb(ec_master_t *);
+
+/*****************************************************************************/
+
+#endif