diff -r 63177d870116 -r 47db5df5c7b3 master/master.c --- a/master/master.c Thu Dec 16 09:52:17 2010 +0100 +++ b/master/master.c Thu Dec 16 11:23:32 2010 +0100 @@ -89,7 +89,7 @@ static int ec_master_idle_thread(void *); static int ec_master_operation_thread(void *); #ifdef EC_EOE -static int ec_master_eoe_thread(void *); +static int ec_master_eoe_processing(ec_master_t *); #endif void ec_master_find_dc_ref_clock(ec_master_t *); @@ -573,9 +573,6 @@ master->phase = EC_ORPHANED; -#ifdef EC_EOE - ec_master_eoe_stop(master); -#endif ec_master_thread_stop(master); down(&master->master_sem); @@ -1301,6 +1298,10 @@ slave++) { ec_fsm_slave_exec(&slave->fsm); // may queue datagram in external queue } +#if defined(EC_EOE) + if (!ec_master_eoe_processing(master)) + master->fsm.idle = 0; // pump the bus as fast as possible +#endif up(&master->master_sem); // queue and send @@ -1360,6 +1361,9 @@ slave++) { ec_fsm_slave_exec(&slave->fsm); // may queue datagram in external queue } +#if defined(EC_EOE) + ec_master_eoe_processing(master); +#endif up(&master->master_sem); #ifdef EC_USE_HRTIMER @@ -1383,119 +1387,48 @@ /*****************************************************************************/ #ifdef EC_EOE -/** Starts Ethernet over EtherCAT processing on demand. - */ -void ec_master_eoe_start(ec_master_t *master /**< EtherCAT master */) -{ - struct sched_param param = { .sched_priority = 0 }; - - if (master->eoe_thread) { - EC_MASTER_WARN(master, "EoE already running!\n"); - return; - } - - if (list_empty(&master->eoe_handlers)) - return; - - if (!master->send_cb || !master->receive_cb) { - EC_MASTER_WARN(master, "No EoE processing" - " because of missing callbacks!\n"); - return; - } - - EC_MASTER_INFO(master, "Starting EoE thread.\n"); - master->eoe_thread = kthread_run(ec_master_eoe_thread, master, - "EtherCAT-EoE"); - if (IS_ERR(master->eoe_thread)) { - int err = (int) PTR_ERR(master->eoe_thread); - EC_MASTER_ERR(master, "Failed to start EoE thread (error %i)!\n", - err); - master->eoe_thread = NULL; - return; - } - - sched_setscheduler(master->eoe_thread, SCHED_NORMAL, ¶m); - set_user_nice(master->eoe_thread, 0); -} - -/*****************************************************************************/ - -/** Stops the Ethernet over EtherCAT processing. - */ -void ec_master_eoe_stop(ec_master_t *master /**< EtherCAT master */) -{ - if (master->eoe_thread) { - EC_MASTER_INFO(master, "Stopping EoE thread.\n"); - - kthread_stop(master->eoe_thread); - master->eoe_thread = NULL; - EC_MASTER_INFO(master, "EoE thread exited.\n"); - } -} /*****************************************************************************/ /** Does the Ethernet over EtherCAT processing. */ -static int ec_master_eoe_thread(void *priv_data) -{ - ec_master_t *master = (ec_master_t *) priv_data; +static int ec_master_eoe_processing(ec_master_t *master) +{ ec_eoe_t *eoe; unsigned int none_open, sth_to_send, all_idle; - - EC_MASTER_DBG(master, 1, "EoE thread running.\n"); - - while (!kthread_should_stop()) { - none_open = 1; - all_idle = 1; - + none_open = 1; + all_idle = 1; + + list_for_each_entry(eoe, &master->eoe_handlers, list) { + if (ec_eoe_is_open(eoe)) { + none_open = 0; + break; + } + } + if (none_open) + return all_idle; + + // actual EoE processing + sth_to_send = 0; + list_for_each_entry(eoe, &master->eoe_handlers, list) { + ec_eoe_run(eoe); + if (eoe->queue_datagram) { + sth_to_send = 1; + } + if (!ec_eoe_is_idle(eoe)) { + all_idle = 0; + } + } + + if (sth_to_send) { list_for_each_entry(eoe, &master->eoe_handlers, list) { - if (ec_eoe_is_open(eoe)) { - none_open = 0; - break; - } - } - if (none_open) - goto schedule; - - // receive datagrams - master->receive_cb(master->cb_data); - - // actual EoE processing - sth_to_send = 0; - list_for_each_entry(eoe, &master->eoe_handlers, list) { - ec_eoe_run(eoe); - if (eoe->queue_datagram) { - sth_to_send = 1; - } - if (!ec_eoe_is_idle(eoe)) { - all_idle = 0; - } - } - - if (sth_to_send) { - list_for_each_entry(eoe, &master->eoe_handlers, list) { - ec_eoe_queue(eoe); - } - // (try to) send datagrams - down(&master->ext_queue_sem); - master->send_cb(master->cb_data); - up(&master->ext_queue_sem); - } - -schedule: - if (all_idle) { - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(1); - } else { - schedule(); - } - } - - EC_MASTER_DBG(master, 1, "EoE thread exiting...\n"); - return 0; -} -#endif + ec_eoe_queue(eoe); + } + } + return all_idle; +} + +#endif // EC_EOE /*****************************************************************************/ @@ -1992,9 +1925,6 @@ uint32_t domain_offset; ec_domain_t *domain; int ret; -#ifdef EC_EOE - int eoe_was_running; -#endif EC_MASTER_DBG(master, 1, "ecrt_master_activate(master = 0x%p)\n", master); @@ -2022,10 +1952,6 @@ // restart EoE process and master thread with new locking ec_master_thread_stop(master); -#ifdef EC_EOE - eoe_was_running = master->eoe_thread != NULL; - ec_master_eoe_stop(master); -#endif EC_MASTER_DBG(master, 1, "FSM datagram is %p.\n", &master->fsm_datagram); @@ -2036,11 +1962,6 @@ master->receive_cb = master->app_receive_cb; master->cb_data = master->app_cb_data; -#ifdef EC_EOE - if (eoe_was_running) { - ec_master_eoe_start(master); - } -#endif ret = ec_master_thread_start(master, ec_master_operation_thread, "EtherCAT-OP"); if (ret < 0) { @@ -2065,7 +1986,6 @@ ec_slave_t *slave; #ifdef EC_EOE ec_eoe_t *eoe; - int eoe_was_running; #endif EC_MASTER_DBG(master, 1, "%s(master = 0x%p)\n", __func__, master); @@ -2076,10 +1996,6 @@ } ec_master_thread_stop(master); -#ifdef EC_EOE - eoe_was_running = master->eoe_thread != NULL; - ec_master_eoe_stop(master); -#endif master->send_cb = ec_master_internal_send_cb; master->receive_cb = ec_master_internal_receive_cb; @@ -2091,32 +2007,32 @@ slave < master->slaves + master->slave_count; slave++) { - // set states for all slaves + // set state to PREOP for all but eoe slaves +#ifdef EC_EOE + // ... but leave EoE slaves in OP + list_for_each_entry(eoe, &master->eoe_handlers, list) { + if (slave != eoe->slave || !ec_eoe_is_open(eoe)) { + ec_slave_request_state(slave, EC_SLAVE_STATE_PREOP); + // mark for reconfiguration, because the master could have no + // possibility for a reconfiguration between two sequential operation + // phases. + slave->force_config = 1; + } + } +#else ec_slave_request_state(slave, EC_SLAVE_STATE_PREOP); - // mark for reconfiguration, because the master could have no // possibility for a reconfiguration between two sequential operation // phases. slave->force_config = 1; - } - -#ifdef EC_EOE - // ... but leave EoE slaves in OP - list_for_each_entry(eoe, &master->eoe_handlers, list) { - if (ec_eoe_is_open(eoe)) - ec_slave_request_state(eoe->slave, EC_SLAVE_STATE_OP); - } -#endif +#endif + + } master->app_time = 0ULL; master->app_start_time = 0ULL; master->has_app_time = 0; -#ifdef EC_EOE - if (eoe_was_running) { - ec_master_eoe_start(master); - } -#endif if (ec_master_thread_start(master, ec_master_idle_thread, "EtherCAT-IDLE")) EC_MASTER_WARN(master, "Failed to restart master thread!\n");