# HG changeset patch # User Martin Troxler # Date 1292510848 -3600 # Node ID 96e2ae6cce953e0b5194dfa201bbf5797640f231 # Parent da133ec36c3a2bbd046bfb535bffb239f51878be ecrt_master_callbacks: replaced send/receive callback mechanism with locking mechanism; removed ecrt_master_send_ext diff -r da133ec36c3a -r 96e2ae6cce95 examples/dc_rtai/dc_rtai_sample.c --- 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))) { diff -r da133ec36c3a -r 96e2ae6cce95 examples/mini/mini.c --- 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))) { diff -r da133ec36c3a -r 96e2ae6cce95 examples/rtai/rtai_sample.c --- 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))) { diff -r da133ec36c3a -r 96e2ae6cce95 examples/tty/tty.c --- 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))) { diff -r da133ec36c3a -r 96e2ae6cce95 include/ecrt.h --- 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. diff -r da133ec36c3a -r 96e2ae6cce95 master/cdev.c --- 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; diff -r da133ec36c3a -r 96e2ae6cce95 master/master.c --- 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); diff -r da133ec36c3a -r 96e2ae6cce95 master/master.h --- 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