Execute master FSM in fast mode also if slave FSM are busy.
This commit is contained in:
parent
26e5b9f553
commit
74ec61add4
|
|
@ -1460,14 +1460,17 @@ void ec_master_nanosleep(const unsigned long nsecs)
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
/** Execute slave FSMs.
|
/** Execute slave FSMs.
|
||||||
|
*
|
||||||
|
* Returns non-zero, if at least one slave FSM is busy.
|
||||||
*/
|
*/
|
||||||
void ec_master_exec_slave_fsms(
|
int ec_master_exec_slave_fsms(
|
||||||
ec_master_t *master /**< EtherCAT master. */
|
ec_master_t *master /**< EtherCAT master. */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
ec_datagram_t *datagram;
|
ec_datagram_t *datagram;
|
||||||
ec_fsm_slave_t *fsm, *next;
|
ec_fsm_slave_t *fsm, *next;
|
||||||
unsigned int count = 0;
|
unsigned int count = 0;
|
||||||
|
int busy = 0;
|
||||||
|
|
||||||
list_for_each_entry_safe(fsm, next, &master->fsm_exec_list, list) {
|
list_for_each_entry_safe(fsm, next, &master->fsm_exec_list, list) {
|
||||||
if (!fsm->datagram) {
|
if (!fsm->datagram) {
|
||||||
|
|
@ -1475,7 +1478,7 @@ void ec_master_exec_slave_fsms(
|
||||||
"This is a bug!\n", fsm->slave->ring_position);
|
"This is a bug!\n", fsm->slave->ring_position);
|
||||||
list_del_init(&fsm->list);
|
list_del_init(&fsm->list);
|
||||||
master->fsm_exec_count--;
|
master->fsm_exec_count--;
|
||||||
return;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fsm->datagram->state == EC_DATAGRAM_INIT ||
|
if (fsm->datagram->state == EC_DATAGRAM_INIT ||
|
||||||
|
|
@ -1483,7 +1486,7 @@ void ec_master_exec_slave_fsms(
|
||||||
fsm->datagram->state == EC_DATAGRAM_SENT) {
|
fsm->datagram->state == EC_DATAGRAM_SENT) {
|
||||||
// previous datagram was not sent or received yet.
|
// previous datagram was not sent or received yet.
|
||||||
// wait until next thread execution
|
// wait until next thread execution
|
||||||
return;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
datagram = ec_master_get_external_datagram(master);
|
datagram = ec_master_get_external_datagram(master);
|
||||||
|
|
@ -1506,6 +1509,7 @@ void ec_master_exec_slave_fsms(
|
||||||
#endif
|
#endif
|
||||||
master->ext_ring_idx_fsm =
|
master->ext_ring_idx_fsm =
|
||||||
(master->ext_ring_idx_fsm + 1) % EC_EXT_RING_SIZE;
|
(master->ext_ring_idx_fsm + 1) % EC_EXT_RING_SIZE;
|
||||||
|
busy = 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// FSM finished
|
// FSM finished
|
||||||
|
|
@ -1530,6 +1534,7 @@ void ec_master_exec_slave_fsms(
|
||||||
list_add_tail(&master->fsm_slave->fsm.list,
|
list_add_tail(&master->fsm_slave->fsm.list,
|
||||||
&master->fsm_exec_list);
|
&master->fsm_exec_list);
|
||||||
master->fsm_exec_count++;
|
master->fsm_exec_count++;
|
||||||
|
busy = 1;
|
||||||
#if DEBUG_INJECT
|
#if DEBUG_INJECT
|
||||||
EC_MASTER_DBG(master, 1, "New slave %u FSM"
|
EC_MASTER_DBG(master, 1, "New slave %u FSM"
|
||||||
" consumed datagram %s, now %u FSMs in list.\n",
|
" consumed datagram %s, now %u FSMs in list.\n",
|
||||||
|
|
@ -1545,6 +1550,8 @@ void ec_master_exec_slave_fsms(
|
||||||
}
|
}
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return busy;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
@ -1554,7 +1561,7 @@ void ec_master_exec_slave_fsms(
|
||||||
static int ec_master_idle_thread(void *priv_data)
|
static int ec_master_idle_thread(void *priv_data)
|
||||||
{
|
{
|
||||||
ec_master_t *master = (ec_master_t *) priv_data;
|
ec_master_t *master = (ec_master_t *) priv_data;
|
||||||
int fsm_exec;
|
int fsm_exec, slave_fsms_busy;
|
||||||
#ifdef EC_USE_HRTIMER
|
#ifdef EC_USE_HRTIMER
|
||||||
size_t sent_bytes;
|
size_t sent_bytes;
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1581,7 +1588,7 @@ static int ec_master_idle_thread(void *priv_data)
|
||||||
|
|
||||||
fsm_exec = ec_fsm_master_exec(&master->fsm);
|
fsm_exec = ec_fsm_master_exec(&master->fsm);
|
||||||
|
|
||||||
ec_master_exec_slave_fsms(master);
|
slave_fsms_busy = ec_master_exec_slave_fsms(master);
|
||||||
|
|
||||||
up(&master->master_sem);
|
up(&master->master_sem);
|
||||||
|
|
||||||
|
|
@ -1597,7 +1604,7 @@ static int ec_master_idle_thread(void *priv_data)
|
||||||
#endif
|
#endif
|
||||||
up(&master->io_sem);
|
up(&master->io_sem);
|
||||||
|
|
||||||
if (ec_fsm_master_idle(&master->fsm)) {
|
if (ec_fsm_master_idle(&master->fsm) && !slave_fsms_busy) {
|
||||||
#ifdef EC_USE_HRTIMER
|
#ifdef EC_USE_HRTIMER
|
||||||
ec_master_nanosleep(master->send_interval * 1000);
|
ec_master_nanosleep(master->send_interval * 1000);
|
||||||
#else
|
#else
|
||||||
|
|
@ -1625,6 +1632,7 @@ static int ec_master_idle_thread(void *priv_data)
|
||||||
static int ec_master_operation_thread(void *priv_data)
|
static int ec_master_operation_thread(void *priv_data)
|
||||||
{
|
{
|
||||||
ec_master_t *master = (ec_master_t *) priv_data;
|
ec_master_t *master = (ec_master_t *) priv_data;
|
||||||
|
int slave_fsms_busy;
|
||||||
|
|
||||||
EC_MASTER_DBG(master, 1, "Operation thread running"
|
EC_MASTER_DBG(master, 1, "Operation thread running"
|
||||||
" with fsm interval = %u us, max data size=%zu\n",
|
" with fsm interval = %u us, max data size=%zu\n",
|
||||||
|
|
@ -1633,6 +1641,8 @@ static int ec_master_operation_thread(void *priv_data)
|
||||||
while (!kthread_should_stop()) {
|
while (!kthread_should_stop()) {
|
||||||
ec_datagram_output_stats(&master->fsm_datagram);
|
ec_datagram_output_stats(&master->fsm_datagram);
|
||||||
|
|
||||||
|
slave_fsms_busy = 0;
|
||||||
|
|
||||||
if (master->injection_seq_rt == master->injection_seq_fsm) {
|
if (master->injection_seq_rt == master->injection_seq_fsm) {
|
||||||
// output statistics
|
// output statistics
|
||||||
ec_master_output_stats(master);
|
ec_master_output_stats(master);
|
||||||
|
|
@ -1648,7 +1658,7 @@ static int ec_master_operation_thread(void *priv_data)
|
||||||
master->injection_seq_fsm++;
|
master->injection_seq_fsm++;
|
||||||
}
|
}
|
||||||
|
|
||||||
ec_master_exec_slave_fsms(master);
|
slave_fsms_busy = ec_master_exec_slave_fsms(master);
|
||||||
|
|
||||||
up(&master->master_sem);
|
up(&master->master_sem);
|
||||||
}
|
}
|
||||||
|
|
@ -1657,7 +1667,7 @@ static int ec_master_operation_thread(void *priv_data)
|
||||||
// the op thread should not work faster than the sending RT thread
|
// the op thread should not work faster than the sending RT thread
|
||||||
ec_master_nanosleep(master->send_interval * 1000);
|
ec_master_nanosleep(master->send_interval * 1000);
|
||||||
#else
|
#else
|
||||||
if (ec_fsm_master_idle(&master->fsm)) {
|
if (ec_fsm_master_idle(&master->fsm) && !slave_fsms_busy) {
|
||||||
set_current_state(TASK_INTERRUPTIBLE);
|
set_current_state(TASK_INTERRUPTIBLE);
|
||||||
schedule_timeout(1);
|
schedule_timeout(1);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue