ecrt_master_callbacks: replaced send/receive callback mechanism with locking mechanism; removed ecrt_master_send_ext
This commit is contained in:
parent
2fcb8f9079
commit
075dce4d7e
|
|
@ -229,8 +229,8 @@ void run(long data)
|
|||
}
|
||||
ecrt_master_sync_slave_clocks(master);
|
||||
ecrt_domain_queue(domain1);
|
||||
ecrt_master_send(master);
|
||||
rt_sem_signal(&master_sem);
|
||||
ecrt_master_send(master);
|
||||
|
||||
rt_task_wait_period();
|
||||
}
|
||||
|
|
@ -238,30 +238,18 @@ void run(long data)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
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);
|
||||
}
|
||||
rt_sem_wait(&master_sem);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void receive_callback(void *cb_data)
|
||||
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 @@ int __init init_mod(void)
|
|||
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))) {
|
||||
|
|
|
|||
|
|
@ -346,10 +346,9 @@ void cyclic_task(unsigned long data)
|
|||
EC_WRITE_U8(domain1_pd + off_dig_out, blink ? 0x06 : 0x09);
|
||||
|
||||
// send process data
|
||||
down(&master_sem);
|
||||
ecrt_domain_queue(domain1);
|
||||
ecrt_master_send(master);
|
||||
up(&master_sem);
|
||||
ecrt_master_send(master);
|
||||
|
||||
// restart timer
|
||||
timer.expires += HZ / FREQUENCY;
|
||||
|
|
@ -358,21 +357,17 @@ void cyclic_task(unsigned long data)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
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 @@ int __init init_mini_module(void)
|
|||
}
|
||||
|
||||
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))) {
|
||||
|
|
|
|||
|
|
@ -234,8 +234,8 @@ void run(long data)
|
|||
|
||||
rt_sem_wait(&master_sem);
|
||||
ecrt_domain_queue(domain1);
|
||||
ecrt_master_send(master);
|
||||
rt_sem_signal(&master_sem);
|
||||
ecrt_master_send(master);
|
||||
|
||||
rt_task_wait_period();
|
||||
}
|
||||
|
|
@ -243,30 +243,18 @@ void run(long data)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
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);
|
||||
}
|
||||
rt_sem_wait(&master_sem);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void receive_callback(void *cb_data)
|
||||
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 @@ int __init init_mod(void)
|
|||
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))) {
|
||||
|
|
|
|||
|
|
@ -141,8 +141,8 @@ void cyclic_task(unsigned long data)
|
|||
// send process data
|
||||
down(&master_sem);
|
||||
ecrt_domain_queue(domain1);
|
||||
ecrt_master_send(master);
|
||||
up(&master_sem);
|
||||
ecrt_master_send(master);
|
||||
|
||||
// restart timer
|
||||
timer.expires += HZ / FREQUENCY;
|
||||
|
|
@ -151,21 +151,17 @@ void cyclic_task(unsigned long data)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
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 @@ int __init init_mini_module(void)
|
|||
}
|
||||
|
||||
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))) {
|
||||
|
|
|
|||
|
|
@ -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 @@ int ecrt_master_reserve(
|
|||
|
||||
/** 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.
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
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 @@ void ecrt_master_receive(
|
|||
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.
|
||||
|
|
|
|||
|
|
@ -1769,9 +1769,6 @@ int ec_cdev_ioctl_activate(
|
|||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -191,12 +191,12 @@ int ec_master_init(ec_master_t *master, /**< EtherCAT master */
|
|||
#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 @@ void ec_master_clear_config(
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** 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 @@ int ec_master_enter_idle_phase(
|
|||
|
||||
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 @@ int ec_master_enter_operation_phase(ec_master_t *master /**< EtherCAT master */)
|
|||
#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 @@ void ec_master_inject_fsm_datagrams(
|
|||
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 @@ void ec_master_inject_fsm_datagrams(
|
|||
}
|
||||
}
|
||||
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 @@ void ec_master_queue_fsm_datagram(
|
|||
{
|
||||
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 @@ void ec_master_queue_fsm_datagram(
|
|||
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 @@ void ec_master_queue_fsm_datagram(
|
|||
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 @@ int ecrt_master_activate(ec_master_t *master)
|
|||
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 @@ void ecrt_master_deactivate(ec_master_t *master)
|
|||
|
||||
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_receive(ec_master_t *master)
|
|||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void ecrt_master_send_ext(ec_master_t *master)
|
||||
{
|
||||
ecrt_master_send(master);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
@ -2226,17 +2204,19 @@ int ecrt_master_get_slave(ec_master_t *master, uint16_t slave_position,
|
|||
/*****************************************************************************/
|
||||
|
||||
void ecrt_master_callbacks(ec_master_t *master,
|
||||
void (*send_cb)(void *), void (*receive_cb)(void *), void *cb_data)
|
||||
void (*lock_cb)(void *), void (*unlock_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);
|
||||
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_send_cb = send_cb;
|
||||
master->app_receive_cb = receive_cb;
|
||||
master->app_cb_data = 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;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void ecrt_master_state(const ec_master_t *master, ec_master_state_t *state)
|
||||
|
|
@ -2482,7 +2462,6 @@ EXPORT_SYMBOL(ecrt_master_create_domain);
|
|||
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);
|
||||
|
|
|
|||
|
|
@ -229,14 +229,12 @@ struct ec_master {
|
|||
|
||||
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 @@ ec_slave_config_t *ecrt_master_slave_config_err(ec_master_t *, uint16_t,
|
|||
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
|
||||
|
|
|
|||
Loading…
Reference in New Issue