# HG changeset patch # User Florian Pose # Date 1173358962 0 # Node ID d5d04c868e0ebedc5f0929bbacf2c412762f9a62 # Parent 9114b3a5f9d33c97d6a8a2f07ca1c5e99c31800a Removed ecrt_master_run(), removed datagram queueing from state machines, added datagram injection, two different master thread functions. diff -r 9114b3a5f9d3 -r d5d04c868e0e NEWS --- a/NEWS Thu Mar 08 08:10:32 2007 +0000 +++ b/NEWS Thu Mar 08 13:02:42 2007 +0000 @@ -16,6 +16,8 @@ * Changed format of sysconfig file and accordingly adjusted functionality of the init script to handle device ID lists. * Realtime interface changes: + - ecrt_master_run() became obsolete, because the master state machine is now + run in process context. - Added ecrt_master_get_status() to get information about the bus. - Added functions to set up an alternative PDO mapping, i. e. ec_slave_pdo_mapping_clear(), ec_slave_pdo_mapping_add() and diff -r 9114b3a5f9d3 -r d5d04c868e0e TODO --- a/TODO Thu Mar 08 08:10:32 2007 +0000 +++ b/TODO Thu Mar 08 13:02:42 2007 +0000 @@ -7,7 +7,6 @@ ------------------------------------------------------------------------------- * Release 1.3: - - Remove ecrt_master_run(). Make master FSM run in process context instead. - Remove addressing scheme "X:Y". - Allow only MAC address as device ID. - Remove ugly ec_slave_is_coupler(). diff -r 9114b3a5f9d3 -r d5d04c868e0e examples/mini/mini.c --- a/examples/mini/mini.c Thu Mar 08 08:10:32 2007 +0000 +++ b/examples/mini/mini.c Thu Mar 08 13:02:42 2007 +0000 @@ -130,8 +130,6 @@ ecrt_domain_queue(domain1); spin_unlock(&master_lock); - ecrt_master_run(master); - spin_lock(&master_lock); ecrt_master_send(master); spin_unlock(&master_lock); diff -r 9114b3a5f9d3 -r d5d04c868e0e examples/rtai/rtai_sample.c --- a/examples/rtai/rtai_sample.c Thu Mar 08 08:10:32 2007 +0000 +++ b/examples/rtai/rtai_sample.c Thu Mar 08 13:02:42 2007 +0000 @@ -91,7 +91,6 @@ rt_sem_wait(&master_sem); ecrt_domain_queue(domain1); - ecrt_master_run(master); ecrt_master_send(master); rt_sem_signal(&master_sem); diff -r 9114b3a5f9d3 -r d5d04c868e0e include/ecrt.h --- a/include/ecrt.h Thu Mar 08 08:10:32 2007 +0000 +++ b/include/ecrt.h Thu Mar 08 13:02:42 2007 +0000 @@ -59,8 +59,8 @@ /*****************************************************************************/ -#define ECRT_VER_MAJOR 1U -#define ECRT_VER_MINOR 2U +#define ECRT_VER_MAJOR 1 +#define ECRT_VER_MINOR 3 #define ECRT_VERSION(a,b) (((a) << 8) + (b)) #define ECRT_VERSION_MAGIC ECRT_VERSION(ECRT_VER_MAJOR, ECRT_VER_MINOR) @@ -150,8 +150,6 @@ void ecrt_master_send(ec_master_t *master); void ecrt_master_receive(ec_master_t *master); -void ecrt_master_run(ec_master_t *master); - ec_slave_t *ecrt_master_get_slave(const ec_master_t *, const char *); void ecrt_master_get_status(const ec_master_t *master, ec_master_status_t *); diff -r 9114b3a5f9d3 -r d5d04c868e0e master/fsm_change.c --- a/master/fsm_change.c Thu Mar 08 08:10:32 2007 +0000 +++ b/master/fsm_change.c Thu Mar 08 13:02:42 2007 +0000 @@ -158,7 +158,6 @@ // write new state to slave ec_datagram_npwr(datagram, slave->station_address, 0x0120, 2); EC_WRITE_U16(datagram->data, fsm->requested_state); - ec_master_queue_datagram(fsm->slave->master, datagram); fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_change_state_check; } @@ -175,10 +174,8 @@ ec_datagram_t *datagram = fsm->datagram; ec_slave_t *slave = fsm->slave; - if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { - ec_master_queue_datagram(fsm->slave->master, datagram); - return; - } + if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) + return; if (datagram->state != EC_DATAGRAM_RECEIVED) { fsm->state = ec_fsm_change_state_error; @@ -206,7 +203,6 @@ // repeat writing new state to slave ec_datagram_npwr(datagram, slave->station_address, 0x0120, 2); EC_WRITE_U16(datagram->data, fsm->requested_state); - ec_master_queue_datagram(fsm->slave->master, datagram); fsm->retries = EC_FSM_RETRIES; return; } @@ -215,7 +211,6 @@ // read AL status from slave ec_datagram_nprd(datagram, slave->station_address, 0x0130, 2); - ec_master_queue_datagram(fsm->slave->master, datagram); fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_change_state_status; } @@ -232,10 +227,8 @@ ec_datagram_t *datagram = fsm->datagram; ec_slave_t *slave = fsm->slave; - if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { - ec_master_queue_datagram(fsm->slave->master, datagram); - return; - } + if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) + return; if (datagram->state != EC_DATAGRAM_RECEIVED) { fsm->state = ec_fsm_change_state_error; @@ -291,7 +284,6 @@ req_state, slave->ring_position, cur_state); // fetch AL status error code ec_datagram_nprd(datagram, slave->station_address, 0x0134, 2); - ec_master_queue_datagram(fsm->slave->master, datagram); fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_change_state_code; return; @@ -312,7 +304,6 @@ again: // no timeout yet. check again ec_datagram_nprd(datagram, slave->station_address, 0x0130, 2); - ec_master_queue_datagram(fsm->slave->master, datagram); fsm->retries = EC_FSM_RETRIES; } @@ -369,10 +360,8 @@ uint32_t code; const ec_code_msg_t *al_msg; - if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { - ec_master_queue_datagram(fsm->slave->master, datagram); - return; - } + if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) + return; if (datagram->state != EC_DATAGRAM_RECEIVED) { fsm->state = ec_fsm_change_state_error; @@ -416,7 +405,6 @@ ec_datagram_npwr(datagram, slave->station_address, 0x0120, 2); EC_WRITE_U16(datagram->data, slave->current_state); - ec_master_queue_datagram(fsm->slave->master, datagram); fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_change_state_ack; } @@ -432,10 +420,8 @@ ec_datagram_t *datagram = fsm->datagram; ec_slave_t *slave = fsm->slave; - if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { - ec_master_queue_datagram(fsm->slave->master, datagram); - return; - } + if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) + return; if (datagram->state != EC_DATAGRAM_RECEIVED) { fsm->state = ec_fsm_change_state_error; @@ -456,7 +442,6 @@ // read new AL status ec_datagram_nprd(datagram, slave->station_address, 0x0130, 2); - ec_master_queue_datagram(fsm->slave->master, datagram); fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_change_state_check_ack; } @@ -473,10 +458,8 @@ ec_datagram_t *datagram = fsm->datagram; ec_slave_t *slave = fsm->slave; - if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { - ec_master_queue_datagram(fsm->slave->master, datagram); - return; - } + if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) + return; if (datagram->state != EC_DATAGRAM_RECEIVED) { fsm->state = ec_fsm_change_state_error; @@ -526,7 +509,6 @@ // reread new AL status ec_datagram_nprd(datagram, slave->station_address, 0x0130, 2); - ec_master_queue_datagram(fsm->slave->master, datagram); fsm->retries = EC_FSM_RETRIES; } diff -r 9114b3a5f9d3 -r d5d04c868e0e master/fsm_coe.c --- a/master/fsm_coe.c Thu Mar 08 08:10:32 2007 +0000 +++ b/master/fsm_coe.c Thu Mar 08 13:02:42 2007 +0000 @@ -260,7 +260,6 @@ EC_WRITE_U16(data + 4, 0x0000); EC_WRITE_U16(data + 6, 0x0001); // deliver all SDOs! - ec_master_queue_datagram(fsm->slave->master, datagram); fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_coe_dict_request; } @@ -277,11 +276,8 @@ ec_datagram_t *datagram = fsm->datagram; ec_slave_t *slave = fsm->slave; - if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { - // FIXME: request again? - ec_master_queue_datagram(fsm->slave->master, datagram); - return; - } + if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) + return; // FIXME: request again? if (datagram->state != EC_DATAGRAM_RECEIVED) { fsm->state = ec_fsm_coe_error; @@ -301,7 +297,6 @@ fsm->cycles_start = datagram->cycles_sent; ec_slave_mbox_prepare_check(slave, datagram); // can not fail. - ec_master_queue_datagram(fsm->slave->master, datagram); fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_coe_dict_check; } @@ -317,10 +312,8 @@ ec_datagram_t *datagram = fsm->datagram; ec_slave_t *slave = fsm->slave; - if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { - ec_master_queue_datagram(fsm->slave->master, datagram); - return; - } + if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) + return; if (datagram->state != EC_DATAGRAM_RECEIVED) { fsm->state = ec_fsm_coe_error; @@ -348,14 +341,12 @@ } ec_slave_mbox_prepare_check(slave, datagram); // can not fail. - ec_master_queue_datagram(fsm->slave->master, datagram); fsm->retries = EC_FSM_RETRIES; return; } // Fetch response ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail. - ec_master_queue_datagram(fsm->slave->master, datagram); fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_coe_dict_response; } @@ -377,11 +368,8 @@ uint16_t sdo_index; ec_sdo_t *sdo; - if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { - // FIXME: request again? - ec_master_queue_datagram(fsm->slave->master, datagram); - return; - } + if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) + return; // FIXME: request again? if (datagram->state != EC_DATAGRAM_RECEIVED) { fsm->state = ec_fsm_coe_error; @@ -464,7 +452,6 @@ if (EC_READ_U8(data + 2) & 0x80) { // more messages waiting. check again. fsm->cycles_start = datagram->cycles_sent; ec_slave_mbox_prepare_check(slave, datagram); // can not fail. - ec_master_queue_datagram(fsm->slave->master, datagram); fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_coe_dict_check; return; @@ -490,7 +477,6 @@ EC_WRITE_U16(data + 4, 0x0000); EC_WRITE_U16(data + 6, fsm->sdo->index); // SDO index - ec_master_queue_datagram(fsm->slave->master, datagram); fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_coe_dict_desc_request; } @@ -507,11 +493,8 @@ ec_datagram_t *datagram = fsm->datagram; ec_slave_t *slave = fsm->slave; - if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { - // FIXME: check for response first? - ec_master_queue_datagram(fsm->slave->master, datagram); - return; - } + if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) + return; // FIXME: check for response first? if (datagram->state != EC_DATAGRAM_RECEIVED) { fsm->state = ec_fsm_coe_error; @@ -531,7 +514,6 @@ fsm->cycles_start = datagram->cycles_sent; ec_slave_mbox_prepare_check(slave, datagram); // can not fail. - ec_master_queue_datagram(fsm->slave->master, datagram); fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_coe_dict_desc_check; } @@ -547,10 +529,8 @@ ec_datagram_t *datagram = fsm->datagram; ec_slave_t *slave = fsm->slave; - if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { - ec_master_queue_datagram(fsm->slave->master, datagram); - return; - } + if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) + return; if (datagram->state != EC_DATAGRAM_RECEIVED) { fsm->state = ec_fsm_coe_error; @@ -577,14 +557,12 @@ } ec_slave_mbox_prepare_check(slave, datagram); // can not fail. - ec_master_queue_datagram(fsm->slave->master, datagram); fsm->retries = EC_FSM_RETRIES; return; } // Fetch response ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail. - ec_master_queue_datagram(fsm->slave->master, datagram); fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_coe_dict_desc_response; } @@ -605,11 +583,8 @@ uint8_t *data, mbox_prot; size_t rec_size, name_size; - if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { - // FIXME: request again? - ec_master_queue_datagram(fsm->slave->master, datagram); - return; - } + if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) + return; // FIXME: request again? if (datagram->state != EC_DATAGRAM_RECEIVED) { fsm->state = ec_fsm_coe_error; @@ -704,7 +679,6 @@ EC_WRITE_U8 (data + 8, fsm->subindex); // SDO subindex EC_WRITE_U8 (data + 9, 0x00); // value info (no values) - ec_master_queue_datagram(fsm->slave->master, datagram); fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_coe_dict_entry_request; } @@ -722,11 +696,8 @@ ec_datagram_t *datagram = fsm->datagram; ec_slave_t *slave = fsm->slave; - if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { - // FIXME: check for response first? - ec_master_queue_datagram(fsm->slave->master, datagram); - return; - } + if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) + return; // FIXME: check for response first? if (datagram->state != EC_DATAGRAM_RECEIVED) { fsm->state = ec_fsm_coe_error; @@ -746,7 +717,6 @@ fsm->cycles_start = datagram->cycles_sent; ec_slave_mbox_prepare_check(slave, datagram); // can not fail - ec_master_queue_datagram(fsm->slave->master, datagram); fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_coe_dict_entry_check; } @@ -763,10 +733,8 @@ ec_datagram_t *datagram = fsm->datagram; ec_slave_t *slave = fsm->slave; - if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { - ec_master_queue_datagram(fsm->slave->master, datagram); - return; - } + if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) + return; if (datagram->state != EC_DATAGRAM_RECEIVED) { fsm->state = ec_fsm_coe_error; @@ -793,14 +761,12 @@ } ec_slave_mbox_prepare_check(slave, datagram); // can not fail. - ec_master_queue_datagram(fsm->slave->master, datagram); fsm->retries = EC_FSM_RETRIES; return; } // Fetch response ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail. - ec_master_queue_datagram(fsm->slave->master, datagram); fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_coe_dict_entry_response; } @@ -822,11 +788,8 @@ size_t rec_size, data_size; ec_sdo_entry_t *entry; - if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { - // FIXME: request again? - ec_master_queue_datagram(fsm->slave->master, datagram); - return; - } + if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) + return; // FIXME: request again? if (datagram->state != EC_DATAGRAM_RECEIVED) { fsm->state = ec_fsm_coe_error; @@ -932,7 +895,6 @@ EC_WRITE_U8 (data + 8, fsm->subindex); // SDO subindex EC_WRITE_U8 (data + 9, 0x00); // value info (no values) - ec_master_queue_datagram(fsm->slave->master, datagram); fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_coe_dict_entry_request; return; @@ -953,7 +915,6 @@ EC_WRITE_U16(data + 4, 0x0000); EC_WRITE_U16(data + 6, fsm->sdo->index); // SDO index - ec_master_queue_datagram(fsm->slave->master, datagram); fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_coe_dict_desc_request; return; @@ -1001,7 +962,6 @@ EC_WRITE_U32(data + 6, sdodata->size); memcpy(data + 10, sdodata->data, sdodata->size); - ec_master_queue_datagram(fsm->slave->master, datagram); fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_coe_down_request; } @@ -1018,11 +978,8 @@ ec_datagram_t *datagram = fsm->datagram; ec_slave_t *slave = fsm->slave; - if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { - // FIXME: check for response first? - ec_master_queue_datagram(fsm->slave->master, datagram); - return; - } + if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) + return; // FIXME: check for response first? if (datagram->state != EC_DATAGRAM_RECEIVED) { fsm->state = ec_fsm_coe_error; @@ -1042,7 +999,6 @@ fsm->cycles_start = datagram->cycles_sent; ec_slave_mbox_prepare_check(slave, datagram); // can not fail. - ec_master_queue_datagram(fsm->slave->master, datagram); fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_coe_down_check; } @@ -1058,10 +1014,8 @@ ec_datagram_t *datagram = fsm->datagram; ec_slave_t *slave = fsm->slave; - if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { - ec_master_queue_datagram(fsm->slave->master, datagram); - return; - } + if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) + return; if (datagram->state != EC_DATAGRAM_RECEIVED) { fsm->state = ec_fsm_coe_error; @@ -1088,14 +1042,12 @@ } ec_slave_mbox_prepare_check(slave, datagram); // can not fail. - ec_master_queue_datagram(fsm->slave->master, datagram); fsm->retries = EC_FSM_RETRIES; return; } // Fetch response ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail. - ec_master_queue_datagram(fsm->slave->master, datagram); fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_coe_down_response; } @@ -1115,11 +1067,8 @@ size_t rec_size; ec_sdo_data_t *sdodata = fsm->sdodata; - if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { - // FIXME: request again? - ec_master_queue_datagram(fsm->slave->master, datagram); - return; - } + if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) + return; // FIXME: request again? if (datagram->state != EC_DATAGRAM_RECEIVED) { fsm->state = ec_fsm_coe_error; @@ -1222,7 +1171,6 @@ ec_print_data(data, 10); } - ec_master_queue_datagram(fsm->slave->master, datagram); fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_coe_up_request; } @@ -1239,11 +1187,8 @@ ec_datagram_t *datagram = fsm->datagram; ec_slave_t *slave = fsm->slave; - if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { - // FIXME: check for response first? - ec_master_queue_datagram(fsm->slave->master, datagram); - return; - } + if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) + return; // FIXME: check for response first? if (datagram->state != EC_DATAGRAM_RECEIVED) { fsm->state = ec_fsm_coe_error; @@ -1263,7 +1208,6 @@ fsm->cycles_start = datagram->cycles_sent; ec_slave_mbox_prepare_check(slave, datagram); // can not fail. - ec_master_queue_datagram(fsm->slave->master, datagram); fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_coe_up_check; } @@ -1279,10 +1223,8 @@ ec_datagram_t *datagram = fsm->datagram; ec_slave_t *slave = fsm->slave; - if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { - ec_master_queue_datagram(fsm->slave->master, datagram); - return; - } + if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) + return; if (datagram->state != EC_DATAGRAM_RECEIVED) { fsm->state = ec_fsm_coe_error; @@ -1309,14 +1251,12 @@ } ec_slave_mbox_prepare_check(slave, datagram); // can not fail. - ec_master_queue_datagram(fsm->slave->master, datagram); fsm->retries = EC_FSM_RETRIES; return; } // Fetch response ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail. - ec_master_queue_datagram(fsm->slave->master, datagram); fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_coe_up_response; } @@ -1341,11 +1281,8 @@ uint32_t complete_size; unsigned int expedited, size_specified; - if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { - // FIXME: request again? - ec_master_queue_datagram(fsm->slave->master, datagram); - return; - } + if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) + return; // FIXME: request again? if (datagram->state != EC_DATAGRAM_RECEIVED) { fsm->state = ec_fsm_coe_error; @@ -1468,7 +1405,6 @@ ec_print_data(data, 3); } - ec_master_queue_datagram(fsm->slave->master, datagram); fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_coe_up_seg_request; return; @@ -1490,11 +1426,8 @@ ec_datagram_t *datagram = fsm->datagram; ec_slave_t *slave = fsm->slave; - if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { - // FIXME: check for response first? - ec_master_queue_datagram(fsm->slave->master, datagram); - return; - } + if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) + return; // FIXME: check for response first? if (datagram->state != EC_DATAGRAM_RECEIVED) { fsm->state = ec_fsm_coe_error; @@ -1514,7 +1447,6 @@ fsm->cycles_start = datagram->cycles_sent; ec_slave_mbox_prepare_check(slave, datagram); // can not fail. - ec_master_queue_datagram(fsm->slave->master, datagram); fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_coe_up_seg_check; } @@ -1530,10 +1462,8 @@ ec_datagram_t *datagram = fsm->datagram; ec_slave_t *slave = fsm->slave; - if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { - ec_master_queue_datagram(fsm->slave->master, datagram); - return; - } + if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) + return; if (datagram->state != EC_DATAGRAM_RECEIVED) { fsm->state = ec_fsm_coe_error; @@ -1560,14 +1490,12 @@ } ec_slave_mbox_prepare_check(slave, datagram); // can not fail. - ec_master_queue_datagram(fsm->slave->master, datagram); fsm->retries = EC_FSM_RETRIES; return; } // Fetch response ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail. - ec_master_queue_datagram(fsm->slave->master, datagram); fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_coe_up_seg_response; } @@ -1592,11 +1520,8 @@ uint32_t seg_size; unsigned int last_segment; - if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { - // FIXME: request again? - ec_master_queue_datagram(fsm->slave->master, datagram); - return; - } + if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) + return; // FIXME: request again? if (datagram->state != EC_DATAGRAM_RECEIVED) { fsm->state = ec_fsm_coe_error; @@ -1686,7 +1611,6 @@ ec_print_data(data, 3); } - ec_master_queue_datagram(fsm->slave->master, datagram); fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_coe_up_seg_request; return; diff -r 9114b3a5f9d3 -r d5d04c868e0e master/fsm_master.c --- a/master/fsm_master.c Thu Mar 08 08:10:32 2007 +0000 +++ b/master/fsm_master.c Thu Mar 08 13:02:42 2007 +0000 @@ -135,19 +135,8 @@ && fsm->state != ec_fsm_master_state_error; } -/*****************************************************************************/ - -/** - \return true, if the master state machine terminated gracefully -*/ - -int ec_fsm_master_success(ec_fsm_master_t *fsm /**< master state machine */) -{ - return fsm->state == ec_fsm_master_state_end; -} - /****************************************************************************** - * operation/idle state machine + * master state machine *****************************************************************************/ /** @@ -158,7 +147,6 @@ void ec_fsm_master_state_start(ec_fsm_master_t *fsm) { ec_datagram_brd(fsm->datagram, 0x0130, 2); - ec_master_queue_datagram(fsm->master, fsm->datagram); fsm->state = ec_fsm_master_state_broadcast; } @@ -176,11 +164,8 @@ ec_slave_t *slave; ec_master_t *master = fsm->master; - if (datagram->state == EC_DATAGRAM_TIMED_OUT) { - // always retry - ec_master_queue_datagram(fsm->master, fsm->datagram); - return; - } + if (datagram->state == EC_DATAGRAM_TIMED_OUT) + return; // always retry if (datagram->state != EC_DATAGRAM_RECEIVED) { // EC_DATAGRAM_ERROR // link is down @@ -260,16 +245,15 @@ // begin scanning of slaves fsm->slave = list_entry(master->slaves.next, ec_slave_t, list); + fsm->state = ec_fsm_master_state_scan_slaves; ec_fsm_slave_start_scan(&fsm->fsm_slave, fsm->slave); ec_fsm_slave_exec(&fsm->fsm_slave); // execute immediately - fsm->state = ec_fsm_master_state_scan_slaves; return; } // fetch state from each slave fsm->slave = list_entry(master->slaves.next, ec_slave_t, list); ec_datagram_nprd(fsm->datagram, fsm->slave->station_address, 0x0130, 2); - ec_master_queue_datagram(master, fsm->datagram); fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_master_state_read_states; } @@ -365,9 +349,9 @@ } fsm->slave = slave; + fsm->state = ec_fsm_master_state_configure_slave; ec_fsm_slave_start_conf(&fsm->fsm_slave, slave); ec_fsm_slave_exec(&fsm->fsm_slave); // execute immediately - fsm->state = ec_fsm_master_state_configure_slave; return; } @@ -391,8 +375,8 @@ else { // start uploading SDO fsm->slave = slave; + fsm->sdo_request = master->sdo_request; fsm->state = ec_fsm_master_state_sdo_request; - fsm->sdo_request = master->sdo_request; ec_fsm_coe_upload(&fsm->fsm_coe, slave, fsm->sdo_request); ec_fsm_coe_exec(&fsm->fsm_coe); // execute immediately return; @@ -446,10 +430,9 @@ // is there another slave to query? if (slave->list.next != &master->slaves) { // process next slave - fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list); + fsm->slave = list_entry(slave->list.next, ec_slave_t, list); ec_datagram_nprd(fsm->datagram, fsm->slave->station_address, 0x0130, 2); - ec_master_queue_datagram(master, fsm->datagram); fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_master_state_read_states; return; @@ -488,10 +471,8 @@ ec_slave_t *slave = fsm->slave; ec_datagram_t *datagram = fsm->datagram; - if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { - ec_master_queue_datagram(fsm->master, fsm->datagram); - return; - } + if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) + return; if (datagram->state != EC_DATAGRAM_RECEIVED) { EC_ERR("Failed to receive AL state datagram for slave %i" @@ -513,9 +494,9 @@ // check, if new slave state has to be acknowledged if (slave->current_state & EC_SLAVE_STATE_ACK_ERR && !slave->error_flag) { + fsm->state = ec_fsm_master_state_acknowledge; ec_fsm_change_ack(&fsm->fsm_change, slave); ec_fsm_change_exec(&fsm->fsm_change); - fsm->state = ec_fsm_master_state_acknowledge; return; } @@ -592,8 +573,7 @@ while (fsm->slave->online_state == EC_SLAVE_ONLINE) { if (fsm->slave->list.next == &fsm->master->slaves) { // last slave? - fsm->state = ec_fsm_master_state_start; - fsm->state(fsm); // execute immediately + fsm->state = ec_fsm_master_state_end; return; } // check next slave @@ -606,7 +586,6 @@ // write station address ec_datagram_apwr(datagram, fsm->slave->ring_position, 0x0010, 2); EC_WRITE_U16(datagram->data, fsm->slave->station_address); - ec_master_queue_datagram(fsm->master, datagram); fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_master_state_rewrite_addresses; } @@ -670,10 +649,8 @@ ec_slave_t *slave = fsm->slave; ec_datagram_t *datagram = fsm->datagram; - if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { - ec_master_queue_datagram(fsm->master, fsm->datagram); - return; - } + if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) + return; if (datagram->state != EC_DATAGRAM_RECEIVED) { EC_ERR("Failed to receive address datagram for slave %i" @@ -691,8 +668,7 @@ } if (fsm->slave->list.next == &fsm->master->slaves) { // last slave? - fsm->state = ec_fsm_master_state_start; - fsm->state(fsm); // execute immediately + fsm->state = ec_fsm_master_state_end; return; } @@ -712,14 +688,14 @@ void ec_fsm_master_state_scan_slaves(ec_fsm_master_t *fsm /**< master state machine */) { ec_master_t *master = fsm->master; - ec_slave_t *slave; + ec_slave_t *slave = fsm->slave; if (ec_fsm_slave_exec(&fsm->fsm_slave)) // execute slave state machine return; // another slave to fetch? - if (fsm->slave->list.next != &master->slaves) { - fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list); + if (slave->list.next != &master->slaves) { + fsm->slave = list_entry(slave->list.next, ec_slave_t, list); ec_fsm_slave_start_scan(&fsm->fsm_slave, fsm->slave); ec_fsm_slave_exec(&fsm->fsm_slave); // execute immediately return; @@ -803,9 +779,7 @@ if (ec_fsm_master_action_process_eeprom(fsm)) return; // processing another request - // restart master state machine. - fsm->state = ec_fsm_master_state_start; - fsm->state(fsm); // execute immediately + fsm->state = ec_fsm_master_state_end; } /*****************************************************************************/ @@ -835,9 +809,7 @@ sdo_count, entry_count, slave->ring_position); } - // restart master state machine. - fsm->state = ec_fsm_master_state_start; - fsm->state(fsm); // execute immediately + fsm->state = ec_fsm_master_state_end; } /*****************************************************************************/ @@ -865,9 +837,7 @@ request->return_code = 1; master->sdo_seq_master++; - // restart master state machine. - fsm->state = ec_fsm_master_state_start; - fsm->state(fsm); // execute immediately + fsm->state = ec_fsm_master_state_end; } /*****************************************************************************/ diff -r 9114b3a5f9d3 -r d5d04c868e0e master/fsm_master.h --- a/master/fsm_master.h Thu Mar 08 08:10:32 2007 +0000 +++ b/master/fsm_master.h Thu Mar 08 13:02:42 2007 +0000 @@ -120,7 +120,6 @@ int ec_fsm_master_exec(ec_fsm_master_t *); int ec_fsm_master_running(ec_fsm_master_t *); -int ec_fsm_master_success(ec_fsm_master_t *); /*****************************************************************************/ diff -r 9114b3a5f9d3 -r d5d04c868e0e master/fsm_sii.c --- a/master/fsm_sii.c Thu Mar 08 08:10:32 2007 +0000 +++ b/master/fsm_sii.c Thu Mar 08 13:02:42 2007 +0000 @@ -168,7 +168,6 @@ EC_WRITE_U8 (datagram->data, 0x00); // read-only access EC_WRITE_U8 (datagram->data + 1, 0x01); // request read operation EC_WRITE_U16(datagram->data + 2, fsm->offset); - ec_master_queue_datagram(fsm->slave->master, datagram); fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_sii_read_check; } @@ -184,10 +183,8 @@ { ec_datagram_t *datagram = fsm->datagram; - if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { - ec_master_queue_datagram(fsm->slave->master, datagram); - return; - } + if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) + return; if (datagram->state != EC_DATAGRAM_RECEIVED) { fsm->state = ec_fsm_sii_error; @@ -216,7 +213,7 @@ ec_datagram_nprd(datagram, fsm->slave->station_address, 0x502, 10); break; } - ec_master_queue_datagram(fsm->slave->master, datagram); + fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_sii_read_fetch; } @@ -232,10 +229,8 @@ { ec_datagram_t *datagram = fsm->datagram; - if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { - ec_master_queue_datagram(fsm->slave->master, datagram); - return; - } + if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) + return; if (datagram->state != EC_DATAGRAM_RECEIVED) { fsm->state = ec_fsm_sii_error; @@ -281,7 +276,6 @@ ec_datagram_nprd(datagram, fsm->slave->station_address, 0x502, 10); break; } - ec_master_queue_datagram(fsm->slave->master, datagram); fsm->retries = EC_FSM_RETRIES; return; } @@ -316,7 +310,7 @@ EC_WRITE_U8 (datagram->data + 1, 0x02); // request write operation EC_WRITE_U32(datagram->data + 2, fsm->offset); memcpy(datagram->data + 6, fsm->value, 2); - ec_master_queue_datagram(fsm->slave->master, datagram); + fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_sii_write_check; } @@ -331,10 +325,8 @@ { ec_datagram_t *datagram = fsm->datagram; - if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { - ec_master_queue_datagram(fsm->slave->master, datagram); - return; - } + if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) + return; if (datagram->state != EC_DATAGRAM_RECEIVED) { fsm->state = ec_fsm_sii_error; @@ -356,7 +348,6 @@ // issue check/fetch datagram ec_datagram_nprd(datagram, fsm->slave->station_address, 0x502, 2); - ec_master_queue_datagram(fsm->slave->master, datagram); fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_sii_write_check2; } @@ -371,10 +362,8 @@ { ec_datagram_t *datagram = fsm->datagram; - if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { - ec_master_queue_datagram(fsm->slave->master, datagram); - return; - } + if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) + return; if (datagram->state != EC_DATAGRAM_RECEIVED) { fsm->state = ec_fsm_sii_error; @@ -404,7 +393,6 @@ } // issue check/fetch datagram again - ec_master_queue_datagram(fsm->slave->master, datagram); fsm->retries = EC_FSM_RETRIES; return; } diff -r 9114b3a5f9d3 -r d5d04c868e0e master/fsm_slave.c --- a/master/fsm_slave.c Thu Mar 08 08:10:32 2007 +0000 +++ b/master/fsm_slave.c Thu Mar 08 13:02:42 2007 +0000 @@ -198,7 +198,6 @@ // write station address ec_datagram_apwr(fsm->datagram, fsm->slave->ring_position, 0x0010, 2); EC_WRITE_U16(fsm->datagram->data, fsm->slave->station_address); - ec_master_queue_datagram(fsm->slave->master, fsm->datagram); fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_slave_scan_state_address; } @@ -213,10 +212,8 @@ { ec_datagram_t *datagram = fsm->datagram; - if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { - ec_master_queue_datagram(fsm->slave->master, fsm->datagram); - return; - } + if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) + return; if (datagram->state != EC_DATAGRAM_RECEIVED) { fsm->state = ec_fsm_slave_state_error; @@ -236,7 +233,6 @@ // Read AL state ec_datagram_nprd(datagram, fsm->slave->station_address, 0x0130, 2); - ec_master_queue_datagram(fsm->slave->master, datagram); fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_slave_scan_state_state; } @@ -252,10 +248,8 @@ ec_datagram_t *datagram = fsm->datagram; ec_slave_t *slave = fsm->slave; - if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { - ec_master_queue_datagram(fsm->slave->master, datagram); - return; - } + if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) + return; if (datagram->state != EC_DATAGRAM_RECEIVED) { fsm->state = ec_fsm_slave_state_error; @@ -283,7 +277,6 @@ // read base data ec_datagram_nprd(datagram, fsm->slave->station_address, 0x0000, 6); - ec_master_queue_datagram(fsm->slave->master, datagram); fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_slave_scan_state_base; } @@ -299,10 +292,8 @@ ec_datagram_t *datagram = fsm->datagram; ec_slave_t *slave = fsm->slave; - if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { - ec_master_queue_datagram(fsm->slave->master, datagram); - return; - } + if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) + return; if (datagram->state != EC_DATAGRAM_RECEIVED) { fsm->state = ec_fsm_slave_state_error; @@ -330,7 +321,6 @@ // read data link status ec_datagram_nprd(datagram, slave->station_address, 0x0110, 2); - ec_master_queue_datagram(slave->master, datagram); fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_slave_scan_state_datalink; } @@ -348,10 +338,8 @@ uint16_t dl_status; unsigned int i; - if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { - ec_master_queue_datagram(fsm->slave->master, datagram); - return; - } + if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) + return; if (datagram->state != EC_DATAGRAM_RECEIVED) { fsm->state = ec_fsm_slave_state_error; @@ -620,7 +608,6 @@ ec_datagram_npwr(datagram, slave->station_address, 0x0600, EC_FMMU_SIZE * slave->base_fmmu_count); memset(datagram->data, 0x00, EC_FMMU_SIZE * slave->base_fmmu_count); - ec_master_queue_datagram(master, datagram); fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_slave_conf_state_clear_fmmus; } @@ -636,10 +623,8 @@ { ec_datagram_t *datagram = fsm->datagram; - if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { - ec_master_queue_datagram(fsm->slave->master, datagram); - return; - } + if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) + return; if (datagram->state != EC_DATAGRAM_RECEIVED) { fsm->state = ec_fsm_slave_state_error; @@ -704,7 +689,6 @@ datagram->data + EC_SYNC_SIZE * i); } - ec_master_queue_datagram(fsm->slave->master, datagram); fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_slave_conf_state_mbox_sync; } @@ -720,10 +704,8 @@ ec_datagram_t *datagram = fsm->datagram; ec_slave_t *slave = fsm->slave; - if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { - ec_master_queue_datagram(fsm->slave->master, datagram); - return; - } + if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) + return; if (datagram->state != EC_DATAGRAM_RECEIVED) { fsm->state = ec_fsm_slave_state_error; @@ -923,7 +905,6 @@ datagram->data + EC_SYNC_SIZE * i); } - ec_master_queue_datagram(fsm->slave->master, datagram); fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_slave_conf_state_pdo_sync; } @@ -938,10 +919,8 @@ ec_datagram_t *datagram = fsm->datagram; ec_slave_t *slave = fsm->slave; - if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { - ec_master_queue_datagram(fsm->slave->master, datagram); - return; - } + if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) + return; if (datagram->state != EC_DATAGRAM_RECEIVED) { fsm->state = ec_fsm_slave_state_error; @@ -970,7 +949,6 @@ void ec_fsm_slave_conf_enter_fmmu(ec_fsm_slave_t *fsm /**< slave state machine */) { ec_slave_t *slave = fsm->slave; - ec_master_t *master = slave->master; ec_datagram_t *datagram = fsm->datagram; unsigned int j; @@ -987,7 +965,6 @@ ec_fmmu_config(&slave->fmmus[j], datagram->data + EC_FMMU_SIZE * j); } - ec_master_queue_datagram(master, datagram); fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_slave_conf_state_fmmu; } @@ -1003,10 +980,8 @@ ec_datagram_t *datagram = fsm->datagram; ec_slave_t *slave = fsm->slave; - if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { - ec_master_queue_datagram(slave->master, datagram); - return; - } + if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) + return; if (datagram->state != EC_DATAGRAM_RECEIVED) { fsm->state = ec_fsm_slave_state_error; diff -r 9114b3a5f9d3 -r d5d04c868e0e master/master.c --- a/master/master.c Thu Mar 08 08:10:32 2007 +0000 +++ b/master/master.c Thu Mar 08 13:02:42 2007 +0000 @@ -57,7 +57,8 @@ void ec_master_clear(struct kobject *); void ec_master_destroy_domains(ec_master_t *); void ec_master_sync_io(ec_master_t *); -static int ec_master_thread(void *); +static int ec_master_idle_thread(ec_master_t *); +static int ec_master_operation_thread(ec_master_t *); void ec_master_eoe_run(unsigned long); void ec_master_check_sdo(unsigned long); int ec_master_measure_bus_time(ec_master_t *); @@ -117,6 +118,8 @@ init_MUTEX(&master->device_sem); master->mode = EC_MASTER_MODE_ORPHANED; + master->injection_seq_fsm = 0; + master->injection_seq_rt = 0; INIT_LIST_HEAD(&master->slaves); master->slave_count = 0; @@ -367,11 +370,25 @@ int ec_master_thread_start(ec_master_t *master /**< EtherCAT master */) { + int (*thread_func)(ec_master_t *); + + switch (master->mode) { + case EC_MASTER_MODE_IDLE: + thread_func = ec_master_idle_thread; + break; + case EC_MASTER_MODE_OPERATION: + thread_func = ec_master_operation_thread; + break; + default: + EC_ERR("Invalid master mode while starting thread!\n"); + return -1; + } + init_completion(&master->thread_exit); - + EC_INFO("Starting master thread.\n"); - if (!(master->thread_id = - kernel_thread(ec_master_thread, master, CLONE_KERNEL))) + if (!(master->thread_id = kernel_thread((int (*)(void *)) thread_func, + master, CLONE_KERNEL))) return -1; return 0; @@ -403,7 +420,7 @@ master->request_cb = ec_master_request_cb; master->release_cb = ec_master_release_cb; master->cb_data = master; - + master->mode = EC_MASTER_MODE_IDLE; if (ec_master_thread_start(master)) { master->mode = EC_MASTER_MODE_ORPHANED; @@ -452,9 +469,10 @@ ecrt_master_receive(master); } - // finish running master FSM + // finish running IDLE FSM if (ec_fsm_master_running(&master->fsm)) { while (ec_fsm_master_exec(&master->fsm)) { + ec_master_queue_datagram(master, &master->fsm_datagram); ec_master_sync_io(master); } } @@ -478,6 +496,8 @@ master->eoe_checked = 0; // allow starting EoE again master->pdo_slaves_offline = 0; // assume all PDO slaves online + master->injection_seq_fsm = 0; + master->injection_seq_rt = 0; return 0; @@ -504,6 +524,9 @@ ec_master_eoe_stop(master); // stop EoE timer master->eoe_checked = 1; // prevent from starting again by FSM + ec_master_thread_stop(master); // stop master thread + master->injection_seq_fsm = 0; + master->injection_seq_rt = 0; // wait for FSM datagram if (master->fsm_datagram.state == EC_DATAGRAM_SENT) { @@ -516,6 +539,7 @@ // finish running master FSM if (ec_fsm_master_running(fsm)) { while (ec_fsm_master_exec(fsm)) { + ec_master_queue_datagram(master, &master->fsm_datagram); ec_master_sync_io(master); } } @@ -538,6 +562,7 @@ ec_fsm_slave_start_conf(&fsm_slave, slave); while (ec_fsm_slave_exec(&fsm_slave)) { + ec_master_queue_datagram(master, &master->fsm_datagram); ec_master_sync_io(master); } } @@ -574,6 +599,8 @@ list_for_each_entry(queued_datagram, &master->datagram_queue, queue) { if (queued_datagram == datagram) { master->stats.skipped++; + if (master->debug_level) + EC_DBG("skipping datagram %x.\n", (unsigned int) datagram); ec_master_output_stats(master); datagram->state = EC_DATAGRAM_QUEUED; return; @@ -826,32 +853,34 @@ /*****************************************************************************/ /** - Master kernel thread function. -*/ - -static int ec_master_thread(void *data) -{ - ec_master_t *master = (ec_master_t *) data; + * Master kernel thread function for IDLE mode. + */ + +static int ec_master_idle_thread(ec_master_t *master) +{ cycles_t cycles_start, cycles_end; - daemonize("EtherCAT"); + daemonize("EtherCAT-IDLE"); allow_signal(SIGTERM); while (!signal_pending(current) && master->mode == EC_MASTER_MODE_IDLE) { cycles_start = get_cycles(); - // receive - spin_lock_bh(&master->internal_lock); - ecrt_master_receive(master); - spin_unlock_bh(&master->internal_lock); + if (ec_fsm_master_running(&master->fsm)) { + // receive + spin_lock_bh(&master->internal_lock); + ecrt_master_receive(master); + spin_unlock_bh(&master->internal_lock); + } // execute master state machine - ec_fsm_master_exec(&master->fsm); - - // send - spin_lock_bh(&master->internal_lock); - ecrt_master_send(master); - spin_unlock_bh(&master->internal_lock); + if (ec_fsm_master_exec(&master->fsm)) { + // queue and send + ec_master_queue_datagram(master, &master->fsm_datagram); + spin_lock_bh(&master->internal_lock); + ecrt_master_send(master); + spin_unlock_bh(&master->internal_lock); + } cycles_end = get_cycles(); master->idle_cycle_times[master->idle_cycle_time_pos] @@ -867,6 +896,52 @@ complete_and_exit(&master->thread_exit, 0); } +/*****************************************************************************/ + +/** + * Master kernel thread function for IDLE mode. + */ + +static int ec_master_operation_thread(ec_master_t *master) +{ + cycles_t cycles_start, cycles_end; + + daemonize("EtherCAT-OP"); + allow_signal(SIGTERM); + + while (!signal_pending(current) && + master->mode == EC_MASTER_MODE_OPERATION) { + + if (master->injection_seq_rt != master->injection_seq_fsm || + master->fsm_datagram.state == EC_DATAGRAM_SENT || + master->fsm_datagram.state == EC_DATAGRAM_QUEUED) + goto schedule; + + cycles_start = get_cycles(); + + // output statistics + ec_master_output_stats(master); + + // execute master state machine + if (ec_fsm_master_exec(&master->fsm)) { + // inject datagram + master->injection_seq_fsm++; + } + + cycles_end = get_cycles(); + master->idle_cycle_times[master->idle_cycle_time_pos] + = (u32) (cycles_end - cycles_start) * 1000 / cpu_khz; + master->idle_cycle_time_pos++; + master->idle_cycle_time_pos %= HZ; + +schedule: + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(1); + } + + master->thread_id = 0; + complete_and_exit(&master->thread_exit, 0); +} /*****************************************************************************/ @@ -1401,6 +1476,7 @@ list_for_each_entry(slave, &master->slaves, list) { ec_fsm_slave_start_conf(&fsm_slave, slave); while (ec_fsm_slave_exec(&fsm_slave)) { + ec_master_queue_datagram(master, &master->fsm_datagram); ec_master_sync_io(master); } @@ -1414,6 +1490,14 @@ ec_fsm_slave_clear(&fsm_slave); ec_master_prepare(master); // prepare asynchronous IO + if (master->debug_level) + EC_DBG("FSM datagram is %x.\n", (unsigned int) &master->fsm_datagram); + + if (ec_master_thread_start(master)) { + EC_ERR("Failed to start master thread!\n"); + return -1; + } + return 0; } @@ -1460,6 +1544,12 @@ { ec_datagram_t *datagram, *n; + if (master->injection_seq_rt != master->injection_seq_fsm) { + // inject datagram produced by master FSM + ec_master_queue_datagram(master, &master->fsm_datagram); + master->injection_seq_rt = master->injection_seq_fsm; + } + if (unlikely(!master->main_device.link_state)) { // link is down, no datagram can be sent list_for_each_entry_safe(datagram, n, &master->datagram_queue, queue) { @@ -1510,22 +1600,6 @@ /*****************************************************************************/ /** - Does all cyclic master work. - \ingroup RealtimeInterface -*/ - -void ecrt_master_run(ec_master_t *master /**< EtherCAT master */) -{ - // output statistics - ec_master_output_stats(master); - - // execute master state machine in a loop - ec_fsm_master_exec(&master->fsm); -} - -/*****************************************************************************/ - -/** Translates an ASCII coded bus-address to a slave pointer. These are the valid addressing schemes: - \a "X" = the X. slave on the bus, @@ -1678,7 +1752,6 @@ EXPORT_SYMBOL(ecrt_master_activate); EXPORT_SYMBOL(ecrt_master_send); EXPORT_SYMBOL(ecrt_master_receive); -EXPORT_SYMBOL(ecrt_master_run); EXPORT_SYMBOL(ecrt_master_callbacks); EXPORT_SYMBOL(ecrt_master_get_slave); EXPORT_SYMBOL(ecrt_master_get_status); diff -r 9114b3a5f9d3 -r d5d04c868e0e master/master.h --- a/master/master.h Thu Mar 08 08:10:32 2007 +0000 +++ b/master/master.h Thu Mar 08 13:02:42 2007 +0000 @@ -109,6 +109,10 @@ ec_fsm_master_t fsm; /**< master state machine */ ec_datagram_t fsm_datagram; /**< datagram used for state machines */ ec_master_mode_t mode; /**< master mode */ + unsigned int injection_seq_fsm; /**< datagram injection sequence number + for the FSM side */ + unsigned int injection_seq_rt; /**< datagram injection sequence number + for the realtime side */ struct list_head slaves; /**< list of slaves on the bus */ unsigned int slave_count; /**< number of slaves on the bus */