48 #include "globals.h" |
48 #include "globals.h" |
49 #include "master.h" |
49 #include "master.h" |
50 #include "slave.h" |
50 #include "slave.h" |
51 #include "device.h" |
51 #include "device.h" |
52 #include "datagram.h" |
52 #include "datagram.h" |
|
53 #ifdef EC_EOE |
53 #include "ethernet.h" |
54 #include "ethernet.h" |
|
55 #endif |
54 |
56 |
55 /*****************************************************************************/ |
57 /*****************************************************************************/ |
56 |
58 |
57 void ec_master_destroy_domains(ec_master_t *); |
59 void ec_master_destroy_domains(ec_master_t *); |
58 void ec_master_sync_io(ec_master_t *); |
60 void ec_master_sync_io(ec_master_t *); |
59 static int ec_master_idle_thread(ec_master_t *); |
61 static int ec_master_idle_thread(ec_master_t *); |
60 static int ec_master_operation_thread(ec_master_t *); |
62 static int ec_master_operation_thread(ec_master_t *); |
|
63 #ifdef EC_EOE |
61 void ec_master_eoe_run(unsigned long); |
64 void ec_master_eoe_run(unsigned long); |
|
65 #endif |
62 void ec_master_check_sdo(unsigned long); |
66 void ec_master_check_sdo(unsigned long); |
63 int ec_master_measure_bus_time(ec_master_t *); |
|
64 ssize_t ec_show_master_attribute(struct kobject *, struct attribute *, char *); |
67 ssize_t ec_show_master_attribute(struct kobject *, struct attribute *, char *); |
65 ssize_t ec_store_master_attribute(struct kobject *, struct attribute *, |
68 ssize_t ec_store_master_attribute(struct kobject *, struct attribute *, |
66 const char *, size_t); |
69 const char *, size_t); |
67 |
70 |
68 /*****************************************************************************/ |
71 /*****************************************************************************/ |
137 INIT_LIST_HEAD(&master->domains); |
140 INIT_LIST_HEAD(&master->domains); |
138 master->debug_level = 0; |
141 master->debug_level = 0; |
139 |
142 |
140 master->stats.timeouts = 0; |
143 master->stats.timeouts = 0; |
141 master->stats.corrupted = 0; |
144 master->stats.corrupted = 0; |
142 master->stats.skipped = 0; |
|
143 master->stats.unmatched = 0; |
145 master->stats.unmatched = 0; |
144 master->stats.output_jiffies = 0; |
146 master->stats.output_jiffies = 0; |
145 |
147 |
146 for (i = 0; i < HZ; i++) { |
148 for (i = 0; i < HZ; i++) { |
147 master->idle_cycle_times[i] = 0; |
149 master->idle_cycle_times[i] = 0; |
|
150 #ifdef EC_EOE |
148 master->eoe_cycle_times[i] = 0; |
151 master->eoe_cycle_times[i] = 0; |
|
152 #endif |
149 } |
153 } |
150 master->idle_cycle_time_pos = 0; |
154 master->idle_cycle_time_pos = 0; |
|
155 #ifdef EC_EOE |
151 master->eoe_cycle_time_pos = 0; |
156 master->eoe_cycle_time_pos = 0; |
152 |
157 |
153 init_timer(&master->eoe_timer); |
158 init_timer(&master->eoe_timer); |
154 master->eoe_timer.function = ec_master_eoe_run; |
159 master->eoe_timer.function = ec_master_eoe_run; |
155 master->eoe_timer.data = (unsigned long) master; |
160 master->eoe_timer.data = (unsigned long) master; |
156 master->eoe_running = 0; |
161 master->eoe_running = 0; |
157 INIT_LIST_HEAD(&master->eoe_handlers); |
162 INIT_LIST_HEAD(&master->eoe_handlers); |
|
163 #endif |
158 |
164 |
159 master->internal_lock = SPIN_LOCK_UNLOCKED; |
165 master->internal_lock = SPIN_LOCK_UNLOCKED; |
160 master->request_cb = NULL; |
166 master->request_cb = NULL; |
161 master->release_cb = NULL; |
167 master->release_cb = NULL; |
162 master->cb_data = NULL; |
168 master->cb_data = NULL; |
176 if (ec_device_init(&master->backup_device, master)) |
182 if (ec_device_init(&master->backup_device, master)) |
177 goto out_clear_main; |
183 goto out_clear_main; |
178 |
184 |
179 // init state machine datagram |
185 // init state machine datagram |
180 ec_datagram_init(&master->fsm_datagram); |
186 ec_datagram_init(&master->fsm_datagram); |
|
187 snprintf(master->fsm_datagram.name, EC_DATAGRAM_NAME_SIZE, "master-fsm"); |
181 if (ec_datagram_prealloc(&master->fsm_datagram, EC_MAX_DATA_SIZE)) { |
188 if (ec_datagram_prealloc(&master->fsm_datagram, EC_MAX_DATA_SIZE)) { |
182 EC_ERR("Failed to allocate FSM datagram.\n"); |
189 EC_ERR("Failed to allocate FSM datagram.\n"); |
183 goto out_clear_backup; |
190 goto out_clear_backup; |
184 } |
191 } |
185 |
192 |
226 |
233 |
227 void ec_master_clear( |
234 void ec_master_clear( |
228 ec_master_t *master /**< EtherCAT master */ |
235 ec_master_t *master /**< EtherCAT master */ |
229 ) |
236 ) |
230 { |
237 { |
|
238 #ifdef EC_EOE |
231 ec_master_clear_eoe_handlers(master); |
239 ec_master_clear_eoe_handlers(master); |
|
240 #endif |
232 ec_master_destroy_slaves(master); |
241 ec_master_destroy_slaves(master); |
233 ec_master_destroy_domains(master); |
242 ec_master_destroy_domains(master); |
234 ec_fsm_master_clear(&master->fsm); |
243 ec_fsm_master_clear(&master->fsm); |
235 ec_datagram_clear(&master->fsm_datagram); |
244 ec_datagram_clear(&master->fsm_datagram); |
236 ec_device_clear(&master->backup_device); |
245 ec_device_clear(&master->backup_device); |
440 |
455 |
441 // set states for all slaves |
456 // set states for all slaves |
442 list_for_each_entry(slave, &master->slaves, list) { |
457 list_for_each_entry(slave, &master->slaves, list) { |
443 ec_slave_request_state(slave, EC_SLAVE_STATE_PREOP); |
458 ec_slave_request_state(slave, EC_SLAVE_STATE_PREOP); |
444 } |
459 } |
|
460 #ifdef EC_EOE |
445 // ... but set EoE slaves to OP |
461 // ... but set EoE slaves to OP |
446 list_for_each_entry(eoe, &master->eoe_handlers, list) { |
462 list_for_each_entry(eoe, &master->eoe_handlers, list) { |
447 if (ec_eoe_is_open(eoe)) |
463 if (ec_eoe_is_open(eoe)) |
448 ec_slave_request_state(eoe->slave, EC_SLAVE_STATE_OP); |
464 ec_slave_request_state(eoe->slave, EC_SLAVE_STATE_OP); |
449 } |
465 } |
|
466 #endif |
450 |
467 |
451 if (master->debug_level) |
468 if (master->debug_level) |
452 EC_DBG("Switching to operation mode.\n"); |
469 EC_DBG("Switching to operation mode.\n"); |
453 |
470 |
454 master->mode = EC_MASTER_MODE_OPERATION; |
471 master->mode = EC_MASTER_MODE_OPERATION; |
473 |
490 |
474 void ec_master_leave_operation_mode(ec_master_t *master |
491 void ec_master_leave_operation_mode(ec_master_t *master |
475 /**< EtherCAT master */) |
492 /**< EtherCAT master */) |
476 { |
493 { |
477 ec_slave_t *slave; |
494 ec_slave_t *slave; |
|
495 #ifdef EC_EOE |
478 ec_eoe_t *eoe; |
496 ec_eoe_t *eoe; |
|
497 #endif |
479 |
498 |
480 master->mode = EC_MASTER_MODE_IDLE; |
499 master->mode = EC_MASTER_MODE_IDLE; |
481 |
500 |
|
501 #ifdef EC_EOE |
482 ec_master_eoe_stop(master); |
502 ec_master_eoe_stop(master); |
|
503 #endif |
483 ec_master_thread_stop(master); |
504 ec_master_thread_stop(master); |
484 |
505 |
485 master->request_cb = ec_master_request_cb; |
506 master->request_cb = ec_master_request_cb; |
486 master->release_cb = ec_master_release_cb; |
507 master->release_cb = ec_master_release_cb; |
487 master->cb_data = master; |
508 master->cb_data = master; |
489 // set states for all slaves |
510 // set states for all slaves |
490 list_for_each_entry(slave, &master->slaves, list) { |
511 list_for_each_entry(slave, &master->slaves, list) { |
491 ec_slave_reset(slave); |
512 ec_slave_reset(slave); |
492 ec_slave_request_state(slave, EC_SLAVE_STATE_PREOP); |
513 ec_slave_request_state(slave, EC_SLAVE_STATE_PREOP); |
493 } |
514 } |
|
515 #ifdef EC_EOE |
494 // ... but leave EoE slaves in OP |
516 // ... but leave EoE slaves in OP |
495 list_for_each_entry(eoe, &master->eoe_handlers, list) { |
517 list_for_each_entry(eoe, &master->eoe_handlers, list) { |
496 if (ec_eoe_is_open(eoe)) |
518 if (ec_eoe_is_open(eoe)) |
497 ec_slave_request_state(eoe->slave, EC_SLAVE_STATE_OP); |
519 ec_slave_request_state(eoe->slave, EC_SLAVE_STATE_OP); |
498 } |
520 } |
|
521 #endif |
499 |
522 |
500 ec_master_destroy_domains(master); |
523 ec_master_destroy_domains(master); |
501 |
524 |
502 if (ec_master_thread_start(master, ec_master_idle_thread)) |
525 if (ec_master_thread_start(master, ec_master_idle_thread)) |
503 EC_WARN("Failed to restart master thread!\n"); |
526 EC_WARN("Failed to restart master thread!\n"); |
|
527 #ifdef EC_EOE |
504 ec_master_eoe_start(master); |
528 ec_master_eoe_start(master); |
|
529 #endif |
505 |
530 |
506 master->allow_scan = 1; |
531 master->allow_scan = 1; |
507 master->allow_config = 1; |
532 master->allow_config = 1; |
508 } |
533 } |
509 |
534 |
520 ec_datagram_t *queued_datagram; |
545 ec_datagram_t *queued_datagram; |
521 |
546 |
522 // check, if the datagram is already queued |
547 // check, if the datagram is already queued |
523 list_for_each_entry(queued_datagram, &master->datagram_queue, queue) { |
548 list_for_each_entry(queued_datagram, &master->datagram_queue, queue) { |
524 if (queued_datagram == datagram) { |
549 if (queued_datagram == datagram) { |
525 master->stats.skipped++; |
550 datagram->skip_count++; |
526 if (master->debug_level) |
551 if (master->debug_level) |
527 EC_DBG("skipping datagram %x.\n", (unsigned int) datagram); |
552 EC_DBG("skipping datagram %x.\n", (unsigned int) datagram); |
528 ec_master_output_stats(master); |
|
529 datagram->state = EC_DATAGRAM_QUEUED; |
553 datagram->state = EC_DATAGRAM_QUEUED; |
530 return; |
554 return; |
531 } |
555 } |
532 } |
556 } |
533 |
557 |
590 EC_WRITE_U16(follows_word, EC_READ_U16(follows_word) | 0x8000); |
614 EC_WRITE_U16(follows_word, EC_READ_U16(follows_word) | 0x8000); |
591 |
615 |
592 // EtherCAT datagram header |
616 // EtherCAT datagram header |
593 EC_WRITE_U8 (cur_data, datagram->type); |
617 EC_WRITE_U8 (cur_data, datagram->type); |
594 EC_WRITE_U8 (cur_data + 1, datagram->index); |
618 EC_WRITE_U8 (cur_data + 1, datagram->index); |
595 EC_WRITE_U32(cur_data + 2, datagram->address.logical); |
619 memcpy(cur_data + 2, datagram->address, EC_ADDR_LEN); |
596 EC_WRITE_U16(cur_data + 6, datagram->data_size & 0x7FF); |
620 EC_WRITE_U16(cur_data + 6, datagram->data_size & 0x7FF); |
597 EC_WRITE_U16(cur_data + 8, 0x0000); |
621 EC_WRITE_U16(cur_data + 8, 0x0000); |
598 follows_word = cur_data + 6; |
622 follows_word = cur_data + 6; |
599 cur_data += EC_DATAGRAM_HEADER_SIZE; |
623 cur_data += EC_DATAGRAM_HEADER_SIZE; |
600 |
624 |
770 if (master->stats.corrupted) { |
794 if (master->stats.corrupted) { |
771 EC_WARN("%i frame%s CORRUPTED!\n", master->stats.corrupted, |
795 EC_WARN("%i frame%s CORRUPTED!\n", master->stats.corrupted, |
772 master->stats.corrupted == 1 ? "" : "s"); |
796 master->stats.corrupted == 1 ? "" : "s"); |
773 master->stats.corrupted = 0; |
797 master->stats.corrupted = 0; |
774 } |
798 } |
775 if (master->stats.skipped) { |
|
776 EC_WARN("%i datagram%s SKIPPED!\n", master->stats.skipped, |
|
777 master->stats.skipped == 1 ? "" : "s"); |
|
778 master->stats.skipped = 0; |
|
779 } |
|
780 if (master->stats.unmatched) { |
799 if (master->stats.unmatched) { |
781 EC_WARN("%i datagram%s UNMATCHED!\n", master->stats.unmatched, |
800 EC_WARN("%i datagram%s UNMATCHED!\n", master->stats.unmatched, |
782 master->stats.unmatched == 1 ? "" : "s"); |
801 master->stats.unmatched == 1 ? "" : "s"); |
783 master->stats.unmatched = 0; |
802 master->stats.unmatched = 0; |
784 } |
803 } |
798 daemonize("EtherCAT-IDLE"); |
817 daemonize("EtherCAT-IDLE"); |
799 allow_signal(SIGTERM); |
818 allow_signal(SIGTERM); |
800 |
819 |
801 while (!signal_pending(current)) { |
820 while (!signal_pending(current)) { |
802 cycles_start = get_cycles(); |
821 cycles_start = get_cycles(); |
|
822 ec_datagram_output_stats(&master->fsm_datagram); |
803 |
823 |
804 if (ec_fsm_master_running(&master->fsm)) { // datagram on the way |
824 if (ec_fsm_master_running(&master->fsm)) { // datagram on the way |
805 // receive |
825 // receive |
806 spin_lock_bh(&master->internal_lock); |
826 spin_lock_bh(&master->internal_lock); |
807 ecrt_master_receive(master); |
827 ecrt_master_receive(master); |
939 ssize_t ec_master_info(ec_master_t *master, /**< EtherCAT master */ |
960 ssize_t ec_master_info(ec_master_t *master, /**< EtherCAT master */ |
940 char *buffer /**< memory to store data */ |
961 char *buffer /**< memory to store data */ |
941 ) |
962 ) |
942 { |
963 { |
943 off_t off = 0; |
964 off_t off = 0; |
|
965 #ifdef EC_EOE |
944 ec_eoe_t *eoe; |
966 ec_eoe_t *eoe; |
|
967 #endif |
945 uint32_t cur, sum, min, max, pos, i; |
968 uint32_t cur, sum, min, max, pos, i; |
946 |
969 |
947 off += sprintf(buffer + off, "\nMode: "); |
970 off += sprintf(buffer + off, "\nMode: "); |
948 switch (master->mode) { |
971 switch (master->mode) { |
949 case EC_MASTER_MODE_ORPHANED: |
972 case EC_MASTER_MODE_ORPHANED: |
957 break; |
980 break; |
958 } |
981 } |
959 |
982 |
960 off += sprintf(buffer + off, "\nSlaves: %i\n", |
983 off += sprintf(buffer + off, "\nSlaves: %i\n", |
961 master->slave_count); |
984 master->slave_count); |
|
985 off += sprintf(buffer + off, "Status: %s\n", |
|
986 master->fsm.tainted ? "TAINTED" : "sane"); |
|
987 off += sprintf(buffer + off, "PDO slaves: %s\n", |
|
988 master->pdo_slaves_offline ? "INCOMPLETE" : "online"); |
962 |
989 |
963 off += sprintf(buffer + off, "\nDevices:\n"); |
990 off += sprintf(buffer + off, "\nDevices:\n"); |
964 |
991 |
965 down(&master->device_sem); |
992 down(&master->device_sem); |
966 off += sprintf(buffer + off, " Main: "); |
993 off += sprintf(buffer + off, " Main: "); |
1004 list_for_each_entry(eoe, &master->eoe_handlers, list) { |
1032 list_for_each_entry(eoe, &master->eoe_handlers, list) { |
1005 off += sprintf(buffer + off, " %s: %u / %u (%u KB/s)\n", |
1033 off += sprintf(buffer + off, " %s: %u / %u (%u KB/s)\n", |
1006 eoe->dev->name, eoe->rx_rate, eoe->tx_rate, |
1034 eoe->dev->name, eoe->rx_rate, eoe->tx_rate, |
1007 ((eoe->rx_rate + eoe->tx_rate) / 8 + 512) / 1024); |
1035 ((eoe->rx_rate + eoe->tx_rate) / 8 + 512) / 1024); |
1008 } |
1036 } |
|
1037 #endif |
1009 |
1038 |
1010 off += sprintf(buffer + off, "\n"); |
1039 off += sprintf(buffer + off, "\n"); |
1011 |
1040 |
1012 return off; |
1041 return off; |
1013 } |
1042 } |
1139 } |
1169 } |
1140 } |
1170 } |
1141 if (none_open) |
1171 if (none_open) |
1142 goto queue_timer; |
1172 goto queue_timer; |
1143 |
1173 |
|
1174 // receive datagrams |
1144 if (master->request_cb(master->cb_data)) goto queue_timer; |
1175 if (master->request_cb(master->cb_data)) goto queue_timer; |
1145 |
|
1146 // receive datagrams |
|
1147 cycles_start = get_cycles(); |
1176 cycles_start = get_cycles(); |
1148 ecrt_master_receive(master); |
1177 ecrt_master_receive(master); |
|
1178 master->release_cb(master->cb_data); |
1149 |
1179 |
1150 // actual EoE processing |
1180 // actual EoE processing |
1151 list_for_each_entry(eoe, &master->eoe_handlers, list) { |
1181 list_for_each_entry(eoe, &master->eoe_handlers, list) { |
1152 ec_eoe_run(eoe); |
1182 ec_eoe_run(eoe); |
1153 } |
1183 } |
1154 |
1184 |
1155 // send datagrams |
1185 // send datagrams |
|
1186 if (master->request_cb(master->cb_data)) { |
|
1187 goto queue_timer; |
|
1188 } |
|
1189 list_for_each_entry(eoe, &master->eoe_handlers, list) { |
|
1190 ec_eoe_queue(eoe); |
|
1191 } |
1156 ecrt_master_send(master); |
1192 ecrt_master_send(master); |
|
1193 master->release_cb(master->cb_data); |
1157 cycles_end = get_cycles(); |
1194 cycles_end = get_cycles(); |
1158 |
|
1159 master->release_cb(master->cb_data); |
|
1160 |
1195 |
1161 master->eoe_cycle_times[master->eoe_cycle_time_pos] |
1196 master->eoe_cycle_times[master->eoe_cycle_time_pos] |
1162 = (u32) (cycles_end - cycles_start) * 1000 / cpu_khz; |
1197 = (u32) (cycles_end - cycles_start) * 1000 / cpu_khz; |
1163 master->eoe_cycle_time_pos++; |
1198 master->eoe_cycle_time_pos++; |
1164 master->eoe_cycle_time_pos %= HZ; |
1199 master->eoe_cycle_time_pos %= HZ; |
1165 |
1200 |
1166 queue_timer: |
1201 queue_timer: |
1167 restart_jiffies = HZ / EC_EOE_FREQUENCY; |
1202 restart_jiffies = HZ / EC_EOE_FREQUENCY; |
1168 if (!restart_jiffies) restart_jiffies = 1; |
1203 if (!restart_jiffies) restart_jiffies = 1; |
1169 master->eoe_timer.expires += restart_jiffies; |
1204 master->eoe_timer.expires = jiffies + restart_jiffies; |
1170 add_timer(&master->eoe_timer); |
1205 add_timer(&master->eoe_timer); |
1171 } |
1206 } |
1172 |
1207 #endif |
1173 /*****************************************************************************/ |
|
1174 |
|
1175 /** |
|
1176 Measures the time, a frame is on the bus. |
|
1177 \return 0 in case of success, else < 0 |
|
1178 */ |
|
1179 |
|
1180 int ec_master_measure_bus_time(ec_master_t *master) |
|
1181 { |
|
1182 ec_datagram_t datagram; |
|
1183 uint32_t cur, sum, min, max, i; |
|
1184 |
|
1185 ec_datagram_init(&datagram); |
|
1186 |
|
1187 if (ec_datagram_brd(&datagram, 0x0130, 2)) { |
|
1188 EC_ERR("Failed to allocate datagram for bus time measuring.\n"); |
|
1189 ec_datagram_clear(&datagram); |
|
1190 return -1; |
|
1191 } |
|
1192 |
|
1193 ecrt_master_receive(master); |
|
1194 |
|
1195 sum = 0; |
|
1196 min = 0xFFFFFFFF; |
|
1197 max = 0; |
|
1198 |
|
1199 for (i = 0; i < 100; i++) { |
|
1200 ec_master_queue_datagram(master, &datagram); |
|
1201 ecrt_master_send(master); |
|
1202 |
|
1203 while (1) { |
|
1204 ecrt_master_receive(master); |
|
1205 |
|
1206 if (datagram.state == EC_DATAGRAM_RECEIVED) { |
|
1207 break; |
|
1208 } |
|
1209 else if (datagram.state == EC_DATAGRAM_ERROR) { |
|
1210 EC_WARN("Failed to measure bus time.\n"); |
|
1211 goto error; |
|
1212 } |
|
1213 else if (datagram.state == EC_DATAGRAM_TIMED_OUT) { |
|
1214 EC_WARN("Timeout while measuring bus time.\n"); |
|
1215 goto error; |
|
1216 } |
|
1217 } |
|
1218 |
|
1219 cur = (unsigned int) (datagram.cycles_received |
|
1220 - datagram.cycles_sent) * 1000 / cpu_khz; |
|
1221 sum += cur; |
|
1222 if (cur > max) max = cur; |
|
1223 if (cur < min) min = cur; |
|
1224 } |
|
1225 |
|
1226 EC_DBG("Bus time is (min/avg/max) %u / %u.%u / %u us.\n", |
|
1227 min, sum / 100, sum % 100, max); |
|
1228 ec_datagram_clear(&datagram); |
|
1229 return 0; |
|
1230 |
|
1231 error: |
|
1232 ec_datagram_clear(&datagram); |
|
1233 return -1; |
|
1234 } |
|
1235 |
1208 |
1236 /*****************************************************************************/ |
1209 /*****************************************************************************/ |
1237 |
1210 |
1238 /** |
1211 /** |
1239 Prepares synchronous IO. |
1212 Prepares synchronous IO. |