IgH EtherCAT Master  1.5.2
master.c
Go to the documentation of this file.
1/******************************************************************************
2 *
3 * Copyright (C) 2006-2020 Florian Pose, Ingenieurgemeinschaft IgH
4 *
5 * This file is part of the IgH EtherCAT Master.
6 *
7 * The IgH EtherCAT Master is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License version 2, as
9 * published by the Free Software Foundation.
10 *
11 * The IgH EtherCAT Master is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
14 * Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with the IgH EtherCAT Master; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 *
20 * ---
21 *
22 * The license mentioned above concerns the source code only. Using the
23 * EtherCAT technology and brand is only permitted in compliance with the
24 * industrial property and similar rights of Beckhoff Automation GmbH.
25 *
26 * vim: expandtab
27 *
28 *****************************************************************************/
29
35/*****************************************************************************/
36
37#include <linux/module.h>
38#include <linux/kernel.h>
39#include <linux/string.h>
40#include <linux/slab.h>
41#include <linux/delay.h>
42#include <linux/device.h>
43#include <linux/version.h>
44#include <linux/hrtimer.h>
45#include <linux/kthread.h>
46
47#include "globals.h"
48#include "slave.h"
49#include "slave_config.h"
50#include "device.h"
51#include "datagram.h"
52
53#ifdef EC_EOE
54#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
55#include <uapi/linux/sched/types.h> // struct sched_param
56#include <linux/sched/types.h> // sched_setscheduler
57#endif
58#include "ethernet.h"
59#endif
60
61#include "master.h"
62
63/*****************************************************************************/
64
67#define DEBUG_INJECT 0
68
71#define FORCE_OUTPUT_CORRUPTED 0
72
74#define EC_SDO_INJECTION_TIMEOUT 10000
75
76#ifdef EC_HAVE_CYCLES
77
80static cycles_t timeout_cycles;
81
84static cycles_t ext_injection_timeout_cycles;
85
86#else
87
90static unsigned long timeout_jiffies;
91
94static unsigned long ext_injection_timeout_jiffies;
95
96#endif
97
100const unsigned int rate_intervals[] = {
101 1, 10, 60
102};
103
104/*****************************************************************************/
105
108static int ec_master_idle_thread(void *);
109static int ec_master_operation_thread(void *);
110#ifdef EC_EOE
111static int ec_master_eoe_thread(void *);
112#endif
116
117/*****************************************************************************/
118
122{
123#ifdef EC_HAVE_CYCLES
124 timeout_cycles = (cycles_t) EC_IO_TIMEOUT /* us */ * (cpu_khz / 1000);
125 ext_injection_timeout_cycles =
126 (cycles_t) EC_SDO_INJECTION_TIMEOUT /* us */ * (cpu_khz / 1000);
127#else
128 // one jiffy may always elapse between time measurement
129 timeout_jiffies = max(EC_IO_TIMEOUT * HZ / 1000000, 1);
131 max(EC_SDO_INJECTION_TIMEOUT * HZ / 1000000, 1);
132#endif
133}
134
135/*****************************************************************************/
136
143 unsigned int index,
144 const uint8_t *main_mac,
145 const uint8_t *backup_mac,
146 dev_t device_number,
147 struct class *class,
148 unsigned int debug_level,
149 unsigned int run_on_cpu
150 )
151{
152 int ret;
153 unsigned int dev_idx, i;
154
155 master->index = index;
156 master->reserved = 0;
157
158 sema_init(&master->master_sem, 1);
159
160 for (dev_idx = EC_DEVICE_MAIN; dev_idx < EC_MAX_NUM_DEVICES; dev_idx++) {
161 master->macs[dev_idx] = NULL;
162 }
163
164 master->macs[EC_DEVICE_MAIN] = main_mac;
165
166#if EC_MAX_NUM_DEVICES > 1
167 master->macs[EC_DEVICE_BACKUP] = backup_mac;
168 master->num_devices = 1 + !ec_mac_is_zero(backup_mac);
169#else
170 if (!ec_mac_is_zero(backup_mac)) {
171 EC_MASTER_WARN(master, "Ignoring backup MAC address!");
172 }
173#endif
174
176
177 sema_init(&master->device_sem, 1);
178
179 master->phase = EC_ORPHANED;
180 master->active = 0;
181 master->config_changed = 0;
182 master->injection_seq_fsm = 0;
183 master->injection_seq_rt = 0;
184
185 master->slaves = NULL;
186 master->slave_count = 0;
187
188 INIT_LIST_HEAD(&master->configs);
189 INIT_LIST_HEAD(&master->domains);
190
191 master->app_time = 0ULL;
192 master->dc_ref_time = 0ULL;
193
194 master->scan_busy = 0;
195 master->allow_scan = 1;
196 sema_init(&master->scan_sem, 1);
197 init_waitqueue_head(&master->scan_queue);
198
199 master->config_busy = 0;
200 sema_init(&master->config_sem, 1);
201 init_waitqueue_head(&master->config_queue);
202
203 INIT_LIST_HEAD(&master->datagram_queue);
204 master->datagram_index = 0;
205
206 INIT_LIST_HEAD(&master->ext_datagram_queue);
207 sema_init(&master->ext_queue_sem, 1);
208
209 master->ext_ring_idx_rt = 0;
210 master->ext_ring_idx_fsm = 0;
211
212 // init external datagram ring
213 for (i = 0; i < EC_EXT_RING_SIZE; i++) {
214 ec_datagram_t *datagram = &master->ext_datagram_ring[i];
215 ec_datagram_init(datagram);
216 snprintf(datagram->name, EC_DATAGRAM_NAME_SIZE, "ext-%u", i);
217 }
218
219 // send interval in IDLE phase
220 ec_master_set_send_interval(master, 1000000 / HZ);
221
222 master->fsm_slave = NULL;
223 INIT_LIST_HEAD(&master->fsm_exec_list);
224 master->fsm_exec_count = 0U;
225
226 master->debug_level = debug_level;
227 master->run_on_cpu = run_on_cpu;
228 master->stats.timeouts = 0;
229 master->stats.corrupted = 0;
230 master->stats.unmatched = 0;
231 master->stats.output_jiffies = 0;
232
233 master->thread = NULL;
234
235#ifdef EC_EOE
236 master->eoe_thread = NULL;
237 INIT_LIST_HEAD(&master->eoe_handlers);
238#endif
239
240 sema_init(&master->io_sem, 1);
241 master->send_cb = NULL;
242 master->receive_cb = NULL;
243 master->cb_data = NULL;
244 master->app_send_cb = NULL;
245 master->app_receive_cb = NULL;
246 master->app_cb_data = NULL;
247
248 INIT_LIST_HEAD(&master->sii_requests);
249 INIT_LIST_HEAD(&master->emerg_reg_requests);
250
251 init_waitqueue_head(&master->request_queue);
252
253 // init devices
254 for (dev_idx = EC_DEVICE_MAIN; dev_idx < ec_master_num_devices(master);
255 dev_idx++) {
256 ret = ec_device_init(&master->devices[dev_idx], master);
257 if (ret < 0) {
258 goto out_clear_devices;
259 }
260 }
261
262 // init state machine datagram
264 snprintf(master->fsm_datagram.name, EC_DATAGRAM_NAME_SIZE, "master-fsm");
266 if (ret < 0) {
268 EC_MASTER_ERR(master, "Failed to allocate FSM datagram.\n");
269 goto out_clear_devices;
270 }
271
272 // create state machine object
273 ec_fsm_master_init(&master->fsm, master, &master->fsm_datagram);
274
275 // alloc external datagram ring
276 for (i = 0; i < EC_EXT_RING_SIZE; i++) {
277 ec_datagram_t *datagram = &master->ext_datagram_ring[i];
278 ret = ec_datagram_prealloc(datagram, EC_MAX_DATA_SIZE);
279 if (ret) {
280 EC_MASTER_ERR(master, "Failed to allocate external"
281 " datagram %u.\n", i);
282 goto out_clear_ext_datagrams;
283 }
284 }
285
286 // init reference sync datagram
289 "refsync");
290 ret = ec_datagram_prealloc(&master->ref_sync_datagram, 4);
291 if (ret < 0) {
293 EC_MASTER_ERR(master, "Failed to allocate reference"
294 " synchronisation datagram.\n");
295 goto out_clear_ext_datagrams;
296 }
297
298 // init sync datagram
300 snprintf(master->sync_datagram.name, EC_DATAGRAM_NAME_SIZE, "sync");
301 ret = ec_datagram_prealloc(&master->sync_datagram, 4);
302 if (ret < 0) {
304 EC_MASTER_ERR(master, "Failed to allocate"
305 " synchronisation datagram.\n");
306 goto out_clear_ref_sync;
307 }
308
309 // init sync monitor datagram
312 "syncmon");
313 ret = ec_datagram_brd(&master->sync_mon_datagram, 0x092c, 4);
314 if (ret < 0) {
316 EC_MASTER_ERR(master, "Failed to allocate sync"
317 " monitoring datagram.\n");
318 goto out_clear_sync;
319 }
320
321 master->dc_ref_config = NULL;
322 master->dc_ref_clock = NULL;
323
324 // init character device
325 ret = ec_cdev_init(&master->cdev, master, device_number);
326 if (ret)
327 goto out_clear_sync_mon;
328
329#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
330 master->class_device = device_create(class, NULL,
331 MKDEV(MAJOR(device_number), master->index), NULL,
332 "EtherCAT%u", master->index);
333#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
334 master->class_device = device_create(class, NULL,
335 MKDEV(MAJOR(device_number), master->index),
336 "EtherCAT%u", master->index);
337#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 15)
338 master->class_device = class_device_create(class, NULL,
339 MKDEV(MAJOR(device_number), master->index), NULL,
340 "EtherCAT%u", master->index);
341#else
342 master->class_device = class_device_create(class,
343 MKDEV(MAJOR(device_number), master->index), NULL,
344 "EtherCAT%u", master->index);
345#endif
346 if (IS_ERR(master->class_device)) {
347 EC_MASTER_ERR(master, "Failed to create class device!\n");
348 ret = PTR_ERR(master->class_device);
349 goto out_clear_cdev;
350 }
351
352#ifdef EC_RTDM
353 // init RTDM device
354 ret = ec_rtdm_dev_init(&master->rtdm_dev, master);
355 if (ret) {
356 goto out_unregister_class_device;
357 }
358#endif
359
360 return 0;
361
362#ifdef EC_RTDM
363out_unregister_class_device:
364#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
365 device_unregister(master->class_device);
366#else
367 class_device_unregister(master->class_device);
368#endif
369#endif
370out_clear_cdev:
371 ec_cdev_clear(&master->cdev);
372out_clear_sync_mon:
374out_clear_sync:
376out_clear_ref_sync:
378out_clear_ext_datagrams:
379 for (i = 0; i < EC_EXT_RING_SIZE; i++) {
381 }
382 ec_fsm_master_clear(&master->fsm);
384out_clear_devices:
385 for (; dev_idx > 0; dev_idx--) {
386 ec_device_clear(&master->devices[dev_idx - 1]);
387 }
388 return ret;
389}
390
391/*****************************************************************************/
392
396 ec_master_t *master
397 )
398{
399 unsigned int dev_idx, i;
400
401#ifdef EC_RTDM
402 ec_rtdm_dev_clear(&master->rtdm_dev);
403#endif
404
405#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
406 device_unregister(master->class_device);
407#else
408 class_device_unregister(master->class_device);
409#endif
410
411 ec_cdev_clear(&master->cdev);
412
413#ifdef EC_EOE
415#endif
419
423
424 for (i = 0; i < EC_EXT_RING_SIZE; i++) {
426 }
427
428 ec_fsm_master_clear(&master->fsm);
430
431 for (dev_idx = EC_DEVICE_MAIN; dev_idx < ec_master_num_devices(master);
432 dev_idx++) {
433 ec_device_clear(&master->devices[dev_idx]);
434 }
435}
436
437/*****************************************************************************/
438
439#ifdef EC_EOE
443 ec_master_t *master
444 )
445{
446 ec_eoe_t *eoe, *next;
447
448 list_for_each_entry_safe(eoe, next, &master->eoe_handlers, list) {
449 list_del(&eoe->list);
450 ec_eoe_clear(eoe);
451 kfree(eoe);
452 }
453}
454#endif
455
456/*****************************************************************************/
457
461{
462 ec_slave_config_t *sc, *next;
463
464 master->dc_ref_config = NULL;
465 master->fsm.sdo_request = NULL; // mark sdo_request as invalid
466
467 list_for_each_entry_safe(sc, next, &master->configs, list) {
468 list_del(&sc->list);
470 kfree(sc);
471 }
472}
473
474/*****************************************************************************/
475
479{
480 ec_slave_t *slave;
481
482 master->dc_ref_clock = NULL;
483
484 // External requests are obsolete, so we wake pending waiters and remove
485 // them from the list.
486
487 while (!list_empty(&master->sii_requests)) {
488 ec_sii_write_request_t *request =
489 list_entry(master->sii_requests.next,
491 list_del_init(&request->list); // dequeue
492 EC_MASTER_WARN(master, "Discarding SII request, slave %u about"
493 " to be deleted.\n", request->slave->ring_position);
494 request->state = EC_INT_REQUEST_FAILURE;
495 wake_up_all(&master->request_queue);
496 }
497
498 master->fsm_slave = NULL;
499 INIT_LIST_HEAD(&master->fsm_exec_list);
500 master->fsm_exec_count = 0;
501
502 for (slave = master->slaves;
503 slave < master->slaves + master->slave_count;
504 slave++) {
505 ec_slave_clear(slave);
506 }
507
508 if (master->slaves) {
509 kfree(master->slaves);
510 master->slaves = NULL;
511 }
512
513 master->slave_count = 0;
514}
515
516/*****************************************************************************/
517
521{
522 ec_domain_t *domain, *next;
523
524 list_for_each_entry_safe(domain, next, &master->domains, list) {
525 list_del(&domain->list);
526 ec_domain_clear(domain);
527 kfree(domain);
528 }
529}
530
531/*****************************************************************************/
532
536 ec_master_t *master
537 )
538{
539 down(&master->master_sem);
542 up(&master->master_sem);
543}
544
545/*****************************************************************************/
546
550 void *cb_data
551 )
552{
553 ec_master_t *master = (ec_master_t *) cb_data;
554 down(&master->io_sem);
555 ecrt_master_send_ext(master);
556 up(&master->io_sem);
557}
558
559/*****************************************************************************/
560
564 void *cb_data
565 )
566{
567 ec_master_t *master = (ec_master_t *) cb_data;
568 down(&master->io_sem);
569 ecrt_master_receive(master);
570 up(&master->io_sem);
571}
572
573/*****************************************************************************/
574
581 ec_master_t *master,
582 int (*thread_func)(void *),
583 const char *name
584 )
585{
586 EC_MASTER_INFO(master, "Starting %s thread.\n", name);
587 master->thread = kthread_create(thread_func, master, name);
588 if (IS_ERR(master->thread)) {
589 int err = (int) PTR_ERR(master->thread);
590 EC_MASTER_ERR(master, "Failed to start master thread (error %i)!\n",
591 err);
592 master->thread = NULL;
593 return err;
594 }
595 if (0xffffffff != master->run_on_cpu) {
596 EC_MASTER_INFO(master, " binding thread to cpu %u\n",master->run_on_cpu);
597 kthread_bind(master->thread,master->run_on_cpu);
598 }
599 /* Ignoring return value of wake_up_process */
600 (void) wake_up_process(master->thread);
601
602 return 0;
603}
604
605/*****************************************************************************/
606
610 ec_master_t *master
611 )
612{
613 unsigned long sleep_jiffies;
614
615 if (!master->thread) {
616 EC_MASTER_WARN(master, "%s(): Already finished!\n", __func__);
617 return;
618 }
619
620 EC_MASTER_DBG(master, 1, "Stopping master thread.\n");
621
622 kthread_stop(master->thread);
623 master->thread = NULL;
624 EC_MASTER_INFO(master, "Master thread exited.\n");
625
626 if (master->fsm_datagram.state != EC_DATAGRAM_SENT) {
627 return;
628 }
629
630 // wait for FSM datagram
631 sleep_jiffies = max(HZ / 100, 1); // 10 ms, at least 1 jiffy
632 schedule_timeout(sleep_jiffies);
633}
634
635/*****************************************************************************/
636
642 ec_master_t *master
643 )
644{
645 int ret;
646 ec_device_index_t dev_idx;
647
648 EC_MASTER_DBG(master, 1, "ORPHANED -> IDLE.\n");
649
652 master->cb_data = master;
653
654 master->phase = EC_IDLE;
655
656 // reset number of responding slaves to trigger scanning
657 for (dev_idx = EC_DEVICE_MAIN; dev_idx < ec_master_num_devices(master);
658 dev_idx++) {
659 master->fsm.slaves_responding[dev_idx] = 0;
660 }
661
663 "EtherCAT-IDLE");
664 if (ret)
665 master->phase = EC_ORPHANED;
666
667 return ret;
668}
669
670/*****************************************************************************/
671
675{
676 EC_MASTER_DBG(master, 1, "IDLE -> ORPHANED.\n");
677
678 master->phase = EC_ORPHANED;
679
680#ifdef EC_EOE
681 ec_master_eoe_stop(master);
682#endif
683 ec_master_thread_stop(master);
684
685 down(&master->master_sem);
687 up(&master->master_sem);
688
689 ec_fsm_master_reset(&master->fsm);
690}
691
692/*****************************************************************************/
693
699 ec_master_t *master
700 )
701{
702 int ret = 0;
703 ec_slave_t *slave;
704#ifdef EC_EOE
705 ec_eoe_t *eoe;
706#endif
707
708 EC_MASTER_DBG(master, 1, "IDLE -> OPERATION.\n");
709
710 down(&master->config_sem);
711 if (master->config_busy) {
712 up(&master->config_sem);
713
714 // wait for slave configuration to complete
715 ret = wait_event_interruptible(master->config_queue,
716 !master->config_busy);
717 if (ret) {
718 EC_MASTER_INFO(master, "Finishing slave configuration"
719 " interrupted by signal.\n");
720 goto out_return;
721 }
722
723 EC_MASTER_DBG(master, 1, "Waiting for pending slave"
724 " configuration returned.\n");
725 } else {
726 up(&master->config_sem);
727 }
728
729 down(&master->scan_sem);
730 master->allow_scan = 0; // 'lock' the slave list
731 if (!master->scan_busy) {
732 up(&master->scan_sem);
733 } else {
734 up(&master->scan_sem);
735
736 // wait for slave scan to complete
737 ret = wait_event_interruptible(master->scan_queue,
738 !master->scan_busy);
739 if (ret) {
740 EC_MASTER_INFO(master, "Waiting for slave scan"
741 " interrupted by signal.\n");
742 goto out_allow;
743 }
744
745 EC_MASTER_DBG(master, 1, "Waiting for pending"
746 " slave scan returned.\n");
747 }
748
749 // set states for all slaves
750 for (slave = master->slaves;
751 slave < master->slaves + master->slave_count;
752 slave++) {
754 }
755
756#ifdef EC_EOE
757 // ... but set EoE slaves to OP
758 list_for_each_entry(eoe, &master->eoe_handlers, list) {
759 if (ec_eoe_is_open(eoe))
761 }
762#endif
763
764 master->phase = EC_OPERATION;
765 master->app_send_cb = NULL;
766 master->app_receive_cb = NULL;
767 master->app_cb_data = NULL;
768 return ret;
769
770out_allow:
771 master->allow_scan = 1;
772out_return:
773 return ret;
774}
775
776/*****************************************************************************/
777
781 ec_master_t *master
782 )
783{
784 if (master->active) {
785 ecrt_master_deactivate(master); // also clears config
786 } else {
788 }
789
790 /* Re-allow scanning for IDLE phase. */
791 master->allow_scan = 1;
792
793 EC_MASTER_DBG(master, 1, "OPERATION -> IDLE.\n");
794
795 master->phase = EC_IDLE;
796}
797
798/*****************************************************************************/
799
803 ec_master_t *master
804 )
805{
806 ec_datagram_t *datagram;
807 size_t queue_size = 0, new_queue_size = 0;
808#if DEBUG_INJECT
809 unsigned int datagram_count = 0;
810#endif
811
812 if (master->ext_ring_idx_rt == master->ext_ring_idx_fsm) {
813 // nothing to inject
814 return;
815 }
816
817 list_for_each_entry(datagram, &master->datagram_queue, queue) {
818 if (datagram->state == EC_DATAGRAM_QUEUED) {
819 queue_size += datagram->data_size;
820 }
821 }
822
823#if DEBUG_INJECT
824 EC_MASTER_DBG(master, 1, "Injecting datagrams, queue_size=%zu\n",
825 queue_size);
826#endif
827
828 while (master->ext_ring_idx_rt != master->ext_ring_idx_fsm) {
829 datagram = &master->ext_datagram_ring[master->ext_ring_idx_rt];
830
831 if (datagram->state != EC_DATAGRAM_INIT) {
832 // skip datagram
833 master->ext_ring_idx_rt =
834 (master->ext_ring_idx_rt + 1) % EC_EXT_RING_SIZE;
835 continue;
836 }
837
838 new_queue_size = queue_size + datagram->data_size;
839 if (new_queue_size <= master->max_queue_size) {
840#if DEBUG_INJECT
841 EC_MASTER_DBG(master, 1, "Injecting datagram %s"
842 " size=%zu, queue_size=%zu\n", datagram->name,
843 datagram->data_size, new_queue_size);
844 datagram_count++;
845#endif
846#ifdef EC_HAVE_CYCLES
847 datagram->cycles_sent = 0;
848#endif
849 datagram->jiffies_sent = 0;
850 ec_master_queue_datagram(master, datagram);
851 queue_size = new_queue_size;
852 }
853 else if (datagram->data_size > master->max_queue_size) {
854 datagram->state = EC_DATAGRAM_ERROR;
855 EC_MASTER_ERR(master, "External datagram %s is too large,"
856 " size=%zu, max_queue_size=%zu\n",
857 datagram->name, datagram->data_size,
858 master->max_queue_size);
859 }
860 else { // datagram does not fit in the current cycle
861#ifdef EC_HAVE_CYCLES
862 cycles_t cycles_now = get_cycles();
863
864 if (cycles_now - datagram->cycles_sent
865 > ext_injection_timeout_cycles)
866#else
867 if (jiffies - datagram->jiffies_sent
869#endif
870 {
871#if defined EC_RT_SYSLOG || DEBUG_INJECT
872 unsigned int time_us;
873#endif
874
875 datagram->state = EC_DATAGRAM_ERROR;
876
877#if defined EC_RT_SYSLOG || DEBUG_INJECT
878#ifdef EC_HAVE_CYCLES
879 time_us = (unsigned int)
880 ((cycles_now - datagram->cycles_sent) * 1000LL)
881 / cpu_khz;
882#else
883 time_us = (unsigned int)
884 ((jiffies - datagram->jiffies_sent) * 1000000 / HZ);
885#endif
886 EC_MASTER_ERR(master, "Timeout %u us: Injecting"
887 " external datagram %s size=%zu,"
888 " max_queue_size=%zu\n", time_us, datagram->name,
889 datagram->data_size, master->max_queue_size);
890#endif
891 }
892 else {
893#if DEBUG_INJECT
894 EC_MASTER_DBG(master, 1, "Deferred injecting"
895 " external datagram %s size=%u, queue_size=%u\n",
896 datagram->name, datagram->data_size, queue_size);
897#endif
898 break;
899 }
900 }
901
902 master->ext_ring_idx_rt =
903 (master->ext_ring_idx_rt + 1) % EC_EXT_RING_SIZE;
904 }
905
906#if DEBUG_INJECT
907 EC_MASTER_DBG(master, 1, "Injected %u datagrams.\n", datagram_count);
908#endif
909}
910
911/*****************************************************************************/
912
917 ec_master_t *master,
918 unsigned int send_interval
919 )
920{
921 master->send_interval = send_interval;
922 master->max_queue_size =
923 (send_interval * 1000) / EC_BYTE_TRANSMISSION_TIME_NS;
924 master->max_queue_size -= master->max_queue_size / 10;
925}
926
927/*****************************************************************************/
928
934 ec_master_t *master
935 )
936{
937 if ((master->ext_ring_idx_fsm + 1) % EC_EXT_RING_SIZE !=
938 master->ext_ring_idx_rt) {
939 ec_datagram_t *datagram =
940 &master->ext_datagram_ring[master->ext_ring_idx_fsm];
941 return datagram;
942 }
943 else {
944 return NULL;
945 }
946}
947
948/*****************************************************************************/
949
953 ec_master_t *master,
954 ec_datagram_t *datagram
955 )
956{
957 ec_datagram_t *queued_datagram;
958
959 /* It is possible, that a datagram in the queue is re-initialized with the
960 * ec_datagram_<type>() methods and then shall be queued with this method.
961 * In that case, the state is already reset to EC_DATAGRAM_INIT. Check if
962 * the datagram is queued to avoid duplicate queuing (which results in an
963 * infinite loop!). Set the state to EC_DATAGRAM_QUEUED again, probably
964 * causing an unmatched datagram. */
965 list_for_each_entry(queued_datagram, &master->datagram_queue, queue) {
966 if (queued_datagram == datagram) {
967 datagram->skip_count++;
968#ifdef EC_RT_SYSLOG
969 EC_MASTER_DBG(master, 1,
970 "Datagram %p already queued (skipping).\n", datagram);
971#endif
972 datagram->state = EC_DATAGRAM_QUEUED;
973 return;
974 }
975 }
976
977 list_add_tail(&datagram->queue, &master->datagram_queue);
978 datagram->state = EC_DATAGRAM_QUEUED;
979}
980
981/*****************************************************************************/
982
986 ec_master_t *master,
987 ec_datagram_t *datagram
988 )
989{
990 down(&master->ext_queue_sem);
991 list_add_tail(&datagram->queue, &master->ext_datagram_queue);
992 up(&master->ext_queue_sem);
993}
994
995/*****************************************************************************/
996
1001 ec_master_t *master,
1002 ec_device_index_t device_index
1003 )
1004{
1005 ec_datagram_t *datagram, *next;
1006 size_t datagram_size;
1007 uint8_t *frame_data, *cur_data = NULL;
1008 void *follows_word;
1009#ifdef EC_HAVE_CYCLES
1010 cycles_t cycles_start, cycles_sent, cycles_end;
1011#endif
1012 unsigned long jiffies_sent;
1013 unsigned int frame_count, more_datagrams_waiting;
1014 struct list_head sent_datagrams;
1015
1016#ifdef EC_HAVE_CYCLES
1017 cycles_start = get_cycles();
1018#endif
1019 frame_count = 0;
1020 INIT_LIST_HEAD(&sent_datagrams);
1021
1022 EC_MASTER_DBG(master, 2, "%s(device_index = %u)\n",
1023 __func__, device_index);
1024
1025 do {
1026 frame_data = NULL;
1027 follows_word = NULL;
1028 more_datagrams_waiting = 0;
1029
1030 // fill current frame with datagrams
1031 list_for_each_entry(datagram, &master->datagram_queue, queue) {
1032 if (datagram->state != EC_DATAGRAM_QUEUED ||
1033 datagram->device_index != device_index) {
1034 continue;
1035 }
1036
1037 if (!frame_data) {
1038 // fetch pointer to transmit socket buffer
1039 frame_data =
1040 ec_device_tx_data(&master->devices[device_index]);
1041 cur_data = frame_data + EC_FRAME_HEADER_SIZE;
1042 }
1043
1044 // does the current datagram fit in the frame?
1045 datagram_size = EC_DATAGRAM_HEADER_SIZE + datagram->data_size
1047 if (cur_data - frame_data + datagram_size > ETH_DATA_LEN) {
1048 more_datagrams_waiting = 1;
1049 break;
1050 }
1051
1052 list_add_tail(&datagram->sent, &sent_datagrams);
1053 datagram->index = master->datagram_index++;
1054
1055 EC_MASTER_DBG(master, 2, "Adding datagram 0x%02X\n",
1056 datagram->index);
1057
1058 // set "datagram following" flag in previous datagram
1059 if (follows_word) {
1060 EC_WRITE_U16(follows_word,
1061 EC_READ_U16(follows_word) | 0x8000);
1062 }
1063
1064 // EtherCAT datagram header
1065 EC_WRITE_U8 (cur_data, datagram->type);
1066 EC_WRITE_U8 (cur_data + 1, datagram->index);
1067 memcpy(cur_data + 2, datagram->address, EC_ADDR_LEN);
1068 EC_WRITE_U16(cur_data + 6, datagram->data_size & 0x7FF);
1069 EC_WRITE_U16(cur_data + 8, 0x0000);
1070 follows_word = cur_data + 6;
1071 cur_data += EC_DATAGRAM_HEADER_SIZE;
1072
1073 // EtherCAT datagram data
1074 memcpy(cur_data, datagram->data, datagram->data_size);
1075 cur_data += datagram->data_size;
1076
1077 // EtherCAT datagram footer
1078 EC_WRITE_U16(cur_data, 0x0000); // reset working counter
1079 cur_data += EC_DATAGRAM_FOOTER_SIZE;
1080 }
1081
1082 if (list_empty(&sent_datagrams)) {
1083 EC_MASTER_DBG(master, 2, "nothing to send.\n");
1084 break;
1085 }
1086
1087 // EtherCAT frame header
1088 EC_WRITE_U16(frame_data, ((cur_data - frame_data
1089 - EC_FRAME_HEADER_SIZE) & 0x7FF) | 0x1000);
1090
1091 // pad frame
1092 while (cur_data - frame_data < ETH_ZLEN - ETH_HLEN)
1093 EC_WRITE_U8(cur_data++, 0x00);
1094
1095 EC_MASTER_DBG(master, 2, "frame size: %zu\n", cur_data - frame_data);
1096
1097 // send frame
1098 ec_device_send(&master->devices[device_index],
1099 cur_data - frame_data);
1100#ifdef EC_HAVE_CYCLES
1101 cycles_sent = get_cycles();
1102#endif
1103 jiffies_sent = jiffies;
1104
1105 // set datagram states and sending timestamps
1106 list_for_each_entry_safe(datagram, next, &sent_datagrams, sent) {
1107 datagram->state = EC_DATAGRAM_SENT;
1108#ifdef EC_HAVE_CYCLES
1109 datagram->cycles_sent = cycles_sent;
1110#endif
1111 datagram->jiffies_sent = jiffies_sent;
1112 list_del_init(&datagram->sent); // empty list of sent datagrams
1113 }
1114
1115 frame_count++;
1116 }
1117 while (more_datagrams_waiting);
1118
1119#ifdef EC_HAVE_CYCLES
1120 if (unlikely(master->debug_level > 1)) {
1121 cycles_end = get_cycles();
1122 EC_MASTER_DBG(master, 0, "%s()"
1123 " sent %u frames in %uus.\n", __func__, frame_count,
1124 (unsigned int) (cycles_end - cycles_start) * 1000 / cpu_khz);
1125 }
1126#endif
1127}
1128
1129/*****************************************************************************/
1130
1138 ec_master_t *master,
1139 ec_device_t *device,
1140 const uint8_t *frame_data,
1141 size_t size
1142 )
1143{
1144 size_t frame_size, data_size;
1145 uint8_t datagram_type, datagram_index;
1146 unsigned int cmd_follows, matched;
1147 const uint8_t *cur_data;
1148 ec_datagram_t *datagram;
1149
1150 if (unlikely(size < EC_FRAME_HEADER_SIZE)) {
1151 if (master->debug_level || FORCE_OUTPUT_CORRUPTED) {
1152 EC_MASTER_DBG(master, 0, "Corrupted frame received"
1153 " on %s (size %zu < %u byte):\n",
1154 device->dev->name, size, EC_FRAME_HEADER_SIZE);
1155 ec_print_data(frame_data, size);
1156 }
1157 master->stats.corrupted++;
1158#ifdef EC_RT_SYSLOG
1159 ec_master_output_stats(master);
1160#endif
1161 return;
1162 }
1163
1164 cur_data = frame_data;
1165
1166 // check length of entire frame
1167 frame_size = EC_READ_U16(cur_data) & 0x07FF;
1168 cur_data += EC_FRAME_HEADER_SIZE;
1169
1170 if (unlikely(frame_size > size)) {
1171 if (master->debug_level || FORCE_OUTPUT_CORRUPTED) {
1172 EC_MASTER_DBG(master, 0, "Corrupted frame received"
1173 " on %s (invalid frame size %zu for "
1174 "received size %zu):\n", device->dev->name,
1175 frame_size, size);
1176 ec_print_data(frame_data, size);
1177 }
1178 master->stats.corrupted++;
1179#ifdef EC_RT_SYSLOG
1180 ec_master_output_stats(master);
1181#endif
1182 return;
1183 }
1184
1185 cmd_follows = 1;
1186 while (cmd_follows) {
1187 // process datagram header
1188 datagram_type = EC_READ_U8 (cur_data);
1189 datagram_index = EC_READ_U8 (cur_data + 1);
1190 data_size = EC_READ_U16(cur_data + 6) & 0x07FF;
1191 cmd_follows = EC_READ_U16(cur_data + 6) & 0x8000;
1192 cur_data += EC_DATAGRAM_HEADER_SIZE;
1193
1194 if (unlikely(cur_data - frame_data
1195 + data_size + EC_DATAGRAM_FOOTER_SIZE > size)) {
1196 if (master->debug_level || FORCE_OUTPUT_CORRUPTED) {
1197 EC_MASTER_DBG(master, 0, "Corrupted frame received"
1198 " on %s (invalid data size %zu):\n",
1199 device->dev->name, data_size);
1200 ec_print_data(frame_data, size);
1201 }
1202 master->stats.corrupted++;
1203#ifdef EC_RT_SYSLOG
1204 ec_master_output_stats(master);
1205#endif
1206 return;
1207 }
1208
1209 // search for matching datagram in the queue
1210 matched = 0;
1211 list_for_each_entry(datagram, &master->datagram_queue, queue) {
1212 if (datagram->index == datagram_index
1213 && datagram->state == EC_DATAGRAM_SENT
1214 && datagram->type == datagram_type
1215 && datagram->data_size == data_size) {
1216 matched = 1;
1217 break;
1218 }
1219 }
1220
1221 // no matching datagram was found
1222 if (!matched) {
1223 master->stats.unmatched++;
1224#ifdef EC_RT_SYSLOG
1225 ec_master_output_stats(master);
1226#endif
1227
1228 if (unlikely(master->debug_level > 0)) {
1229 EC_MASTER_DBG(master, 0, "UNMATCHED datagram:\n");
1231 EC_DATAGRAM_HEADER_SIZE + data_size
1233#ifdef EC_DEBUG_RING
1234 ec_device_debug_ring_print(&master->devices[EC_DEVICE_MAIN]);
1235#endif
1236 }
1237
1238 cur_data += data_size + EC_DATAGRAM_FOOTER_SIZE;
1239 continue;
1240 }
1241
1242 if (datagram->type != EC_DATAGRAM_APWR &&
1243 datagram->type != EC_DATAGRAM_FPWR &&
1244 datagram->type != EC_DATAGRAM_BWR &&
1245 datagram->type != EC_DATAGRAM_LWR) {
1246 // copy received data into the datagram memory,
1247 // if something has been read
1248 memcpy(datagram->data, cur_data, data_size);
1249 }
1250 cur_data += data_size;
1251
1252 // set the datagram's working counter
1253 datagram->working_counter = EC_READ_U16(cur_data);
1254 cur_data += EC_DATAGRAM_FOOTER_SIZE;
1255
1256 // dequeue the received datagram
1257 datagram->state = EC_DATAGRAM_RECEIVED;
1258#ifdef EC_HAVE_CYCLES
1259 datagram->cycles_received =
1260 master->devices[EC_DEVICE_MAIN].cycles_poll;
1261#endif
1262 datagram->jiffies_received =
1264 list_del_init(&datagram->queue);
1265 }
1266}
1267
1268/*****************************************************************************/
1269
1276{
1277 if (unlikely(jiffies - master->stats.output_jiffies >= HZ)) {
1278 master->stats.output_jiffies = jiffies;
1279
1280 if (master->stats.timeouts) {
1281 EC_MASTER_WARN(master, "%u datagram%s TIMED OUT!\n",
1282 master->stats.timeouts,
1283 master->stats.timeouts == 1 ? "" : "s");
1284 master->stats.timeouts = 0;
1285 }
1286 if (master->stats.corrupted) {
1287 EC_MASTER_WARN(master, "%u frame%s CORRUPTED!\n",
1288 master->stats.corrupted,
1289 master->stats.corrupted == 1 ? "" : "s");
1290 master->stats.corrupted = 0;
1291 }
1292 if (master->stats.unmatched) {
1293 EC_MASTER_WARN(master, "%u datagram%s UNMATCHED!\n",
1294 master->stats.unmatched,
1295 master->stats.unmatched == 1 ? "" : "s");
1296 master->stats.unmatched = 0;
1297 }
1298 }
1299}
1300
1301/*****************************************************************************/
1302
1306 ec_master_t *master
1307 )
1308{
1309 unsigned int i;
1310
1311 // zero frame statistics
1312 master->device_stats.tx_count = 0;
1313 master->device_stats.last_tx_count = 0;
1314 master->device_stats.rx_count = 0;
1315 master->device_stats.last_rx_count = 0;
1316 master->device_stats.tx_bytes = 0;
1317 master->device_stats.last_tx_bytes = 0;
1318 master->device_stats.rx_bytes = 0;
1319 master->device_stats.last_rx_bytes = 0;
1320 master->device_stats.last_loss = 0;
1321
1322 for (i = 0; i < EC_RATE_COUNT; i++) {
1323 master->device_stats.tx_frame_rates[i] = 0;
1324 master->device_stats.rx_frame_rates[i] = 0;
1325 master->device_stats.tx_byte_rates[i] = 0;
1326 master->device_stats.rx_byte_rates[i] = 0;
1327 master->device_stats.loss_rates[i] = 0;
1328 }
1329
1330 master->device_stats.jiffies = 0;
1331}
1332
1333/*****************************************************************************/
1334
1338 ec_master_t *master
1339 )
1340{
1341 ec_device_stats_t *s = &master->device_stats;
1342 s32 tx_frame_rate, rx_frame_rate, tx_byte_rate, rx_byte_rate, loss_rate;
1343 u64 loss;
1344 unsigned int i, dev_idx;
1345
1346 // frame statistics
1347 if (likely(jiffies - s->jiffies < HZ)) {
1348 return;
1349 }
1350
1351 tx_frame_rate = (s->tx_count - s->last_tx_count) * 1000;
1352 rx_frame_rate = (s->rx_count - s->last_rx_count) * 1000;
1353 tx_byte_rate = s->tx_bytes - s->last_tx_bytes;
1354 rx_byte_rate = s->rx_bytes - s->last_rx_bytes;
1355 loss = s->tx_count - s->rx_count;
1356 loss_rate = (loss - s->last_loss) * 1000;
1357
1358 /* Low-pass filter:
1359 * Y_n = y_(n - 1) + T / tau * (x - y_(n - 1)) | T = 1
1360 * -> Y_n += (x - y_(n - 1)) / tau
1361 */
1362 for (i = 0; i < EC_RATE_COUNT; i++) {
1363 s32 n = rate_intervals[i];
1364 s->tx_frame_rates[i] += (tx_frame_rate - s->tx_frame_rates[i]) / n;
1365 s->rx_frame_rates[i] += (rx_frame_rate - s->rx_frame_rates[i]) / n;
1366 s->tx_byte_rates[i] += (tx_byte_rate - s->tx_byte_rates[i]) / n;
1367 s->rx_byte_rates[i] += (rx_byte_rate - s->rx_byte_rates[i]) / n;
1368 s->loss_rates[i] += (loss_rate - s->loss_rates[i]) / n;
1369 }
1370
1371 s->last_tx_count = s->tx_count;
1372 s->last_rx_count = s->rx_count;
1373 s->last_tx_bytes = s->tx_bytes;
1374 s->last_rx_bytes = s->rx_bytes;
1375 s->last_loss = loss;
1376
1377 for (dev_idx = EC_DEVICE_MAIN; dev_idx < ec_master_num_devices(master);
1378 dev_idx++) {
1379 ec_device_update_stats(&master->devices[dev_idx]);
1380 }
1381
1382 s->jiffies = jiffies;
1383}
1384
1385/*****************************************************************************/
1386
1387#ifdef EC_USE_HRTIMER
1388
1389/*
1390 * Sleep related functions:
1391 */
1392static enum hrtimer_restart ec_master_nanosleep_wakeup(struct hrtimer *timer)
1393{
1394 struct hrtimer_sleeper *t =
1395 container_of(timer, struct hrtimer_sleeper, timer);
1396 struct task_struct *task = t->task;
1397
1398 t->task = NULL;
1399 if (task)
1400 wake_up_process(task);
1401
1402 return HRTIMER_NORESTART;
1403}
1404
1405/*****************************************************************************/
1406
1407#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
1408
1409/* compatibility with new hrtimer interface */
1410static inline ktime_t hrtimer_get_expires(const struct hrtimer *timer)
1411{
1412 return timer->expires;
1413}
1414
1415/*****************************************************************************/
1416
1417static inline void hrtimer_set_expires(struct hrtimer *timer, ktime_t time)
1418{
1419 timer->expires = time;
1420}
1421
1422#endif
1423
1424/*****************************************************************************/
1425
1426void ec_master_nanosleep(const unsigned long nsecs)
1427{
1428 struct hrtimer_sleeper t;
1429 enum hrtimer_mode mode = HRTIMER_MODE_REL;
1430
1431 hrtimer_init(&t.timer, CLOCK_MONOTONIC, mode);
1432 t.timer.function = ec_master_nanosleep_wakeup;
1433 t.task = current;
1434#ifdef CONFIG_HIGH_RES_TIMERS
1435#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 24)
1436 t.timer.cb_mode = HRTIMER_CB_IRQSAFE_NO_RESTART;
1437#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 26)
1438 t.timer.cb_mode = HRTIMER_CB_IRQSAFE_NO_SOFTIRQ;
1439#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 28)
1440 t.timer.cb_mode = HRTIMER_CB_IRQSAFE_UNLOCKED;
1441#endif
1442#endif
1443 hrtimer_set_expires(&t.timer, ktime_set(0, nsecs));
1444
1445 do {
1446 set_current_state(TASK_INTERRUPTIBLE);
1447 hrtimer_start(&t.timer, hrtimer_get_expires(&t.timer), mode);
1448
1449 if (likely(t.task))
1450 schedule();
1451
1452 hrtimer_cancel(&t.timer);
1453 mode = HRTIMER_MODE_ABS;
1454
1455 } while (t.task && !signal_pending(current));
1456}
1457
1458#endif // EC_USE_HRTIMER
1459
1460/*****************************************************************************/
1461
1465 ec_master_t *master
1466 )
1467{
1468 ec_datagram_t *datagram;
1469 ec_fsm_slave_t *fsm, *next;
1470 unsigned int count = 0;
1471
1472 list_for_each_entry_safe(fsm, next, &master->fsm_exec_list, list) {
1473 if (!fsm->datagram) {
1474 EC_MASTER_WARN(master, "Slave %u FSM has zero datagram."
1475 "This is a bug!\n", fsm->slave->ring_position);
1476 list_del_init(&fsm->list);
1477 master->fsm_exec_count--;
1478 return;
1479 }
1480
1481 if (fsm->datagram->state == EC_DATAGRAM_INIT ||
1483 fsm->datagram->state == EC_DATAGRAM_SENT) {
1484 // previous datagram was not sent or received yet.
1485 // wait until next thread execution
1486 return;
1487 }
1488
1489 datagram = ec_master_get_external_datagram(master);
1490 if (!datagram) {
1491 // no free datagrams at the moment
1492 EC_MASTER_WARN(master, "No free datagram during"
1493 " slave FSM execution. This is a bug!\n");
1494 continue;
1495 }
1496
1497#if DEBUG_INJECT
1498 EC_MASTER_DBG(master, 1, "Executing slave %u FSM.\n",
1499 fsm->slave->ring_position);
1500#endif
1501 if (ec_fsm_slave_exec(fsm, datagram)) {
1502 // FSM consumed datagram
1503#if DEBUG_INJECT
1504 EC_MASTER_DBG(master, 1, "FSM consumed datagram %s\n",
1505 datagram->name);
1506#endif
1507 master->ext_ring_idx_fsm =
1508 (master->ext_ring_idx_fsm + 1) % EC_EXT_RING_SIZE;
1509 }
1510 else {
1511 // FSM finished
1512 list_del_init(&fsm->list);
1513 master->fsm_exec_count--;
1514#if DEBUG_INJECT
1515 EC_MASTER_DBG(master, 1, "FSM finished. %u remaining.\n",
1516 master->fsm_exec_count);
1517#endif
1518 }
1519 }
1520
1521 while (master->fsm_exec_count < EC_EXT_RING_SIZE / 2
1522 && count < master->slave_count) {
1523
1524 if (ec_fsm_slave_is_ready(&master->fsm_slave->fsm)) {
1525 datagram = ec_master_get_external_datagram(master);
1526
1527 if (ec_fsm_slave_exec(&master->fsm_slave->fsm, datagram)) {
1528 master->ext_ring_idx_fsm =
1529 (master->ext_ring_idx_fsm + 1) % EC_EXT_RING_SIZE;
1530 list_add_tail(&master->fsm_slave->fsm.list,
1531 &master->fsm_exec_list);
1532 master->fsm_exec_count++;
1533#if DEBUG_INJECT
1534 EC_MASTER_DBG(master, 1, "New slave %u FSM"
1535 " consumed datagram %s, now %u FSMs in list.\n",
1536 master->fsm_slave->ring_position, datagram->name,
1537 master->fsm_exec_count);
1538#endif
1539 }
1540 }
1541
1542 master->fsm_slave++;
1543 if (master->fsm_slave >= master->slaves + master->slave_count) {
1544 master->fsm_slave = master->slaves;
1545 }
1546 count++;
1547 }
1548}
1549
1550/*****************************************************************************/
1551
1554static int ec_master_idle_thread(void *priv_data)
1555{
1556 ec_master_t *master = (ec_master_t *) priv_data;
1557 int fsm_exec;
1558#ifdef EC_USE_HRTIMER
1559 size_t sent_bytes;
1560#endif
1561
1562 // send interval in IDLE phase
1563 ec_master_set_send_interval(master, 1000000 / HZ);
1564
1565 EC_MASTER_DBG(master, 1, "Idle thread running with send interval = %u us,"
1566 " max data size=%zu\n", master->send_interval,
1567 master->max_queue_size);
1568
1569 while (!kthread_should_stop()) {
1571
1572 // receive
1573 down(&master->io_sem);
1574 ecrt_master_receive(master);
1575 up(&master->io_sem);
1576
1577 // execute master & slave state machines
1578 if (down_interruptible(&master->master_sem)) {
1579 break;
1580 }
1581
1582 fsm_exec = ec_fsm_master_exec(&master->fsm);
1583
1585
1586 up(&master->master_sem);
1587
1588 // queue and send
1589 down(&master->io_sem);
1590 if (fsm_exec) {
1591 ec_master_queue_datagram(master, &master->fsm_datagram);
1592 }
1593 ecrt_master_send(master);
1594#ifdef EC_USE_HRTIMER
1595 sent_bytes = master->devices[EC_DEVICE_MAIN].tx_skb[
1596 master->devices[EC_DEVICE_MAIN].tx_ring_index]->len;
1597#endif
1598 up(&master->io_sem);
1599
1600 if (ec_fsm_master_idle(&master->fsm)) {
1601#ifdef EC_USE_HRTIMER
1602 ec_master_nanosleep(master->send_interval * 1000);
1603#else
1604 set_current_state(TASK_INTERRUPTIBLE);
1605 schedule_timeout(1);
1606#endif
1607 } else {
1608#ifdef EC_USE_HRTIMER
1609 ec_master_nanosleep(sent_bytes * EC_BYTE_TRANSMISSION_TIME_NS);
1610#else
1611 schedule();
1612#endif
1613 }
1614 }
1615
1616 EC_MASTER_DBG(master, 1, "Master IDLE thread exiting...\n");
1617
1618 return 0;
1619}
1620
1621/*****************************************************************************/
1622
1625static int ec_master_operation_thread(void *priv_data)
1626{
1627 ec_master_t *master = (ec_master_t *) priv_data;
1628
1629 EC_MASTER_DBG(master, 1, "Operation thread running"
1630 " with fsm interval = %u us, max data size=%zu\n",
1631 master->send_interval, master->max_queue_size);
1632
1633 while (!kthread_should_stop()) {
1635
1636 if (master->injection_seq_rt == master->injection_seq_fsm) {
1637 // output statistics
1638 ec_master_output_stats(master);
1639
1640 // execute master & slave state machines
1641 if (down_interruptible(&master->master_sem)) {
1642 break;
1643 }
1644
1645 if (ec_fsm_master_exec(&master->fsm)) {
1646 // Inject datagrams (let the RT thread queue them, see
1647 // ecrt_master_send())
1648 master->injection_seq_fsm++;
1649 }
1650
1652
1653 up(&master->master_sem);
1654 }
1655
1656#ifdef EC_USE_HRTIMER
1657 // the op thread should not work faster than the sending RT thread
1658 ec_master_nanosleep(master->send_interval * 1000);
1659#else
1660 if (ec_fsm_master_idle(&master->fsm)) {
1661 set_current_state(TASK_INTERRUPTIBLE);
1662 schedule_timeout(1);
1663 }
1664 else {
1665 schedule();
1666 }
1667#endif
1668 }
1669
1670 EC_MASTER_DBG(master, 1, "Master OP thread exiting...\n");
1671 return 0;
1672}
1673
1674/*****************************************************************************/
1675
1676#ifdef EC_EOE
1677
1678/* compatibility for priority changes */
1679static inline void set_normal_priority(struct task_struct *p, int nice)
1680{
1681#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0)
1682 sched_set_normal(p, nice);
1683#else
1684 struct sched_param param = { .sched_priority = 0 };
1685 sched_setscheduler(p, SCHED_NORMAL, &param);
1686 set_user_nice(p, nice);
1687#endif
1688}
1689
1690/*****************************************************************************/
1691
1695{
1696 if (master->eoe_thread) {
1697 EC_MASTER_WARN(master, "EoE already running!\n");
1698 return;
1699 }
1700
1701 if (list_empty(&master->eoe_handlers))
1702 return;
1703
1704 if (!master->send_cb || !master->receive_cb) {
1705 EC_MASTER_WARN(master, "No EoE processing"
1706 " because of missing callbacks!\n");
1707 return;
1708 }
1709
1710 EC_MASTER_INFO(master, "Starting EoE thread.\n");
1711 master->eoe_thread = kthread_run(ec_master_eoe_thread, master,
1712 "EtherCAT-EoE");
1713 if (IS_ERR(master->eoe_thread)) {
1714 int err = (int) PTR_ERR(master->eoe_thread);
1715 EC_MASTER_ERR(master, "Failed to start EoE thread (error %i)!\n",
1716 err);
1717 master->eoe_thread = NULL;
1718 return;
1719 }
1720
1721 set_normal_priority(master->eoe_thread, 0);
1722}
1723
1724/*****************************************************************************/
1725
1729{
1730 if (master->eoe_thread) {
1731 EC_MASTER_INFO(master, "Stopping EoE thread.\n");
1732
1733 kthread_stop(master->eoe_thread);
1734 master->eoe_thread = NULL;
1735 EC_MASTER_INFO(master, "EoE thread exited.\n");
1736 }
1737}
1738
1739/*****************************************************************************/
1740
1743static int ec_master_eoe_thread(void *priv_data)
1744{
1745 ec_master_t *master = (ec_master_t *) priv_data;
1746 ec_eoe_t *eoe;
1747 unsigned int none_open, sth_to_send, all_idle;
1748
1749 EC_MASTER_DBG(master, 1, "EoE thread running.\n");
1750
1751 while (!kthread_should_stop()) {
1752 none_open = 1;
1753 all_idle = 1;
1754
1755 list_for_each_entry(eoe, &master->eoe_handlers, list) {
1756 if (ec_eoe_is_open(eoe)) {
1757 none_open = 0;
1758 break;
1759 }
1760 }
1761 if (none_open)
1762 goto schedule;
1763
1764 // receive datagrams
1765 master->receive_cb(master->cb_data);
1766
1767 // actual EoE processing
1768 sth_to_send = 0;
1769 list_for_each_entry(eoe, &master->eoe_handlers, list) {
1770 ec_eoe_run(eoe);
1771 if (eoe->queue_datagram) {
1772 sth_to_send = 1;
1773 }
1774 if (!ec_eoe_is_idle(eoe)) {
1775 all_idle = 0;
1776 }
1777 }
1778
1779 if (sth_to_send) {
1780 list_for_each_entry(eoe, &master->eoe_handlers, list) {
1781 ec_eoe_queue(eoe);
1782 }
1783 // (try to) send datagrams
1784 down(&master->ext_queue_sem);
1785 master->send_cb(master->cb_data);
1786 up(&master->ext_queue_sem);
1787 }
1788
1789schedule:
1790 if (all_idle) {
1791 set_current_state(TASK_INTERRUPTIBLE);
1792 schedule_timeout(1);
1793 } else {
1794 schedule();
1795 }
1796 }
1797
1798 EC_MASTER_DBG(master, 1, "EoE thread exiting...\n");
1799 return 0;
1800}
1801
1802#endif
1803
1804/*****************************************************************************/
1805
1809 ec_master_t *master
1810 )
1811{
1813
1814 list_for_each_entry(sc, &master->configs, list) {
1816 }
1817}
1818
1819/*****************************************************************************/
1820
1824#define EC_FIND_SLAVE \
1825 do { \
1826 if (alias) { \
1827 for (; slave < master->slaves + master->slave_count; \
1828 slave++) { \
1829 if (slave->effective_alias == alias) \
1830 break; \
1831 } \
1832 if (slave == master->slaves + master->slave_count) \
1833 return NULL; \
1834 } \
1835 \
1836 slave += position; \
1837 if (slave < master->slaves + master->slave_count) { \
1838 return slave; \
1839 } else { \
1840 return NULL; \
1841 } \
1842 } while (0)
1843
1849 ec_master_t *master,
1850 uint16_t alias,
1851 uint16_t position
1852 )
1853{
1854 ec_slave_t *slave = master->slaves;
1856}
1857
1865 const ec_master_t *master,
1866 uint16_t alias,
1867 uint16_t position
1868 )
1869{
1870 const ec_slave_t *slave = master->slaves;
1872}
1873
1874/*****************************************************************************/
1875
1881 const ec_master_t *master
1882 )
1883{
1884 const ec_slave_config_t *sc;
1885 unsigned int count = 0;
1886
1887 list_for_each_entry(sc, &master->configs, list) {
1888 count++;
1889 }
1890
1891 return count;
1892}
1893
1894/*****************************************************************************/
1895
1899#define EC_FIND_CONFIG \
1900 do { \
1901 list_for_each_entry(sc, &master->configs, list) { \
1902 if (pos--) \
1903 continue; \
1904 return sc; \
1905 } \
1906 return NULL; \
1907 } while (0)
1908
1914 const ec_master_t *master,
1915 unsigned int pos
1916 )
1917{
1920}
1921
1929 const ec_master_t *master,
1930 unsigned int pos
1931 )
1932{
1933 const ec_slave_config_t *sc;
1935}
1936
1937/*****************************************************************************/
1938
1944 const ec_master_t *master
1945 )
1946{
1947 const ec_domain_t *domain;
1948 unsigned int count = 0;
1949
1950 list_for_each_entry(domain, &master->domains, list) {
1951 count++;
1952 }
1953
1954 return count;
1955}
1956
1957/*****************************************************************************/
1958
1962#define EC_FIND_DOMAIN \
1963 do { \
1964 list_for_each_entry(domain, &master->domains, list) { \
1965 if (index--) \
1966 continue; \
1967 return domain; \
1968 } \
1969 \
1970 return NULL; \
1971 } while (0)
1972
1978 ec_master_t *master,
1979 unsigned int index
1980 )
1981{
1982 ec_domain_t *domain;
1984}
1985
1993 const ec_master_t *master,
1994 unsigned int index
1995 )
1996{
1997 const ec_domain_t *domain;
1999}
2000
2001/*****************************************************************************/
2002
2003#ifdef EC_EOE
2004
2010 const ec_master_t *master
2011 )
2012{
2013 const ec_eoe_t *eoe;
2014 unsigned int count = 0;
2015
2016 list_for_each_entry(eoe, &master->eoe_handlers, list) {
2017 count++;
2018 }
2019
2020 return count;
2021}
2022
2023/*****************************************************************************/
2024
2032 const ec_master_t *master,
2033 uint16_t index
2034 )
2035{
2036 const ec_eoe_t *eoe;
2037
2038 list_for_each_entry(eoe, &master->eoe_handlers, list) {
2039 if (index--)
2040 continue;
2041 return eoe;
2042 }
2043
2044 return NULL;
2045}
2046
2047#endif
2048
2049/*****************************************************************************/
2050
2057 ec_master_t *master,
2058 unsigned int level
2059 )
2060{
2061 if (level > 2) {
2062 EC_MASTER_ERR(master, "Invalid debug level %u!\n", level);
2063 return -EINVAL;
2064 }
2065
2066 if (level != master->debug_level) {
2067 master->debug_level = level;
2068 EC_MASTER_INFO(master, "Master debug level set to %u.\n",
2069 master->debug_level);
2070 }
2071
2072 return 0;
2073}
2074
2075/*****************************************************************************/
2076
2080 ec_master_t *master
2081 )
2082{
2083 ec_slave_t *slave, *ref = NULL;
2084
2085 if (master->dc_ref_config) {
2086 // Use application-selected reference clock
2087 slave = master->dc_ref_config->slave;
2088
2089 if (slave) {
2090 if (slave->base_dc_supported && slave->has_dc_system_time) {
2091 ref = slave;
2092 }
2093 else {
2094 EC_MASTER_WARN(master, "Slave %u can not act as a"
2095 " DC reference clock!", slave->ring_position);
2096 }
2097 }
2098 else {
2099 EC_MASTER_WARN(master, "DC reference clock config (%u-%u)"
2100 " has no slave attached!\n", master->dc_ref_config->alias,
2101 master->dc_ref_config->position);
2102 }
2103 }
2104 else {
2105 // Use first slave with DC support as reference clock
2106 for (slave = master->slaves;
2107 slave < master->slaves + master->slave_count;
2108 slave++) {
2109 if (slave->base_dc_supported && slave->has_dc_system_time) {
2110 ref = slave;
2111 break;
2112 }
2113 }
2114
2115 }
2116
2117 master->dc_ref_clock = ref;
2118
2119 if (ref) {
2120 EC_MASTER_INFO(master, "Using slave %u as DC reference clock.\n",
2121 ref->ring_position);
2122 }
2123 else {
2124 EC_MASTER_INFO(master, "No DC reference clock found.\n");
2125 }
2126
2127 // These calls always succeed, because the
2128 // datagrams have been pre-allocated.
2130 ref ? ref->station_address : 0xffff, 0x0910, 4);
2132 ref ? ref->station_address : 0xffff, 0x0910, 4);
2133}
2134
2135/*****************************************************************************/
2136
2142 ec_master_t *master,
2143 ec_slave_t *port0_slave,
2144 unsigned int *slave_position
2145 )
2146{
2147 ec_slave_t *slave = master->slaves + *slave_position;
2148 unsigned int port_index;
2149 int ret;
2150
2151 static const unsigned int next_table[EC_MAX_PORTS] = {
2152 3, 2, 0, 1
2153 };
2154
2155 slave->ports[0].next_slave = port0_slave;
2156
2157 port_index = 3;
2158 while (port_index != 0) {
2159 if (!slave->ports[port_index].link.loop_closed) {
2160 *slave_position = *slave_position + 1;
2161 if (*slave_position < master->slave_count) {
2162 slave->ports[port_index].next_slave =
2163 master->slaves + *slave_position;
2164 ret = ec_master_calc_topology_rec(master,
2165 slave, slave_position);
2166 if (ret) {
2167 return ret;
2168 }
2169 } else {
2170 return -1;
2171 }
2172 }
2173
2174 port_index = next_table[port_index];
2175 }
2176
2177 return 0;
2178}
2179
2180/*****************************************************************************/
2181
2185 ec_master_t *master
2186 )
2187{
2188 unsigned int slave_position = 0;
2189
2190 if (master->slave_count == 0)
2191 return;
2192
2193 if (ec_master_calc_topology_rec(master, NULL, &slave_position))
2194 EC_MASTER_ERR(master, "Failed to calculate bus topology.\n");
2195}
2196
2197/*****************************************************************************/
2198
2202 ec_master_t *master
2203 )
2204{
2205 ec_slave_t *slave;
2206
2207 for (slave = master->slaves;
2208 slave < master->slaves + master->slave_count;
2209 slave++) {
2211 }
2212
2213 if (master->dc_ref_clock) {
2214 uint32_t delay = 0;
2216 }
2217}
2218
2219/*****************************************************************************/
2220
2224 ec_master_t *master
2225 )
2226{
2227 // find DC reference clock
2229
2230 // calculate bus topology
2232
2234}
2235
2236/*****************************************************************************/
2237
2241 ec_master_t *master
2242 )
2243{
2244 unsigned int i;
2245 ec_slave_t *slave;
2246
2247 if (!master->active)
2248 return;
2249
2250 EC_MASTER_DBG(master, 1, "Requesting OP...\n");
2251
2252 // request OP for all configured slaves
2253 for (i = 0; i < master->slave_count; i++) {
2254 slave = master->slaves + i;
2255 if (slave->config) {
2257 }
2258 }
2259
2260 // always set DC reference clock to OP
2261 if (master->dc_ref_clock) {
2263 }
2264}
2265
2266/******************************************************************************
2267 * Application interface
2268 *****************************************************************************/
2269
2275 ec_master_t *master
2276 )
2277{
2278 ec_domain_t *domain, *last_domain;
2279 unsigned int index;
2280
2281 EC_MASTER_DBG(master, 1, "ecrt_master_create_domain(master = 0x%p)\n",
2282 master);
2283
2284 if (!(domain =
2285 (ec_domain_t *) kmalloc(sizeof(ec_domain_t), GFP_KERNEL))) {
2286 EC_MASTER_ERR(master, "Error allocating domain memory!\n");
2287 return ERR_PTR(-ENOMEM);
2288 }
2289
2290 down(&master->master_sem);
2291
2292 if (list_empty(&master->domains)) {
2293 index = 0;
2294 } else {
2295 last_domain = list_entry(master->domains.prev, ec_domain_t, list);
2296 index = last_domain->index + 1;
2297 }
2298
2299 ec_domain_init(domain, master, index);
2300 list_add_tail(&domain->list, &master->domains);
2301
2302 up(&master->master_sem);
2303
2304 EC_MASTER_DBG(master, 1, "Created domain %u.\n", domain->index);
2305
2306 return domain;
2307}
2308
2309/*****************************************************************************/
2310
2312 ec_master_t *master
2313 )
2314{
2316 return IS_ERR(d) ? NULL : d;
2317}
2318
2319/*****************************************************************************/
2320
2322{
2323 uint32_t domain_offset;
2324 ec_domain_t *domain;
2325 int ret;
2326#ifdef EC_EOE
2327 int eoe_was_running;
2328#endif
2329
2330 EC_MASTER_DBG(master, 1, "ecrt_master_activate(master = 0x%p)\n", master);
2331
2332 if (master->active) {
2333 EC_MASTER_WARN(master, "%s: Master already active!\n", __func__);
2334 return 0;
2335 }
2336
2337 down(&master->master_sem);
2338
2339 // finish all domains
2340 domain_offset = 0;
2341 list_for_each_entry(domain, &master->domains, list) {
2342 ret = ec_domain_finish(domain, domain_offset);
2343 if (ret < 0) {
2344 up(&master->master_sem);
2345 EC_MASTER_ERR(master, "Failed to finish domain 0x%p!\n", domain);
2346 return ret;
2347 }
2348 domain_offset += domain->data_size;
2349 }
2350
2351 up(&master->master_sem);
2352
2353 // restart EoE process and master thread with new locking
2354
2355 ec_master_thread_stop(master);
2356#ifdef EC_EOE
2357 eoe_was_running = master->eoe_thread != NULL;
2358 ec_master_eoe_stop(master);
2359#endif
2360
2361 EC_MASTER_DBG(master, 1, "FSM datagram is %p.\n", &master->fsm_datagram);
2362
2363 master->injection_seq_fsm = 0;
2364 master->injection_seq_rt = 0;
2365
2366 master->send_cb = master->app_send_cb;
2367 master->receive_cb = master->app_receive_cb;
2368 master->cb_data = master->app_cb_data;
2369
2370#ifdef EC_EOE
2371 if (eoe_was_running) {
2372 ec_master_eoe_start(master);
2373 }
2374#endif
2376 "EtherCAT-OP");
2377 if (ret < 0) {
2378 EC_MASTER_ERR(master, "Failed to start master thread!\n");
2379 return ret;
2380 }
2381
2382 /* Allow scanning after a topology change. */
2383 master->allow_scan = 1;
2384
2385 master->active = 1;
2386
2387 // notify state machine, that the configuration shall now be applied
2388 master->config_changed = 1;
2389
2390 return 0;
2391}
2392
2393/*****************************************************************************/
2394
2396{
2397 ec_slave_t *slave;
2398#ifdef EC_EOE
2399 ec_eoe_t *eoe;
2400 int eoe_was_running;
2401#endif
2402
2403 EC_MASTER_DBG(master, 1, "%s(master = 0x%p)\n", __func__, master);
2404
2405 if (!master->active) {
2406 EC_MASTER_WARN(master, "%s: Master not active.\n", __func__);
2407 return;
2408 }
2409
2410 ec_master_thread_stop(master);
2411#ifdef EC_EOE
2412 eoe_was_running = master->eoe_thread != NULL;
2413 ec_master_eoe_stop(master);
2414#endif
2415
2418 master->cb_data = master;
2419
2420 ec_master_clear_config(master);
2421
2422 for (slave = master->slaves;
2423 slave < master->slaves + master->slave_count;
2424 slave++) {
2425
2426 // set states for all slaves
2428
2429 // mark for reconfiguration, because the master could have no
2430 // possibility for a reconfiguration between two sequential operation
2431 // phases.
2432 slave->force_config = 1;
2433 }
2434
2435#ifdef EC_EOE
2436 // ... but leave EoE slaves in OP
2437 list_for_each_entry(eoe, &master->eoe_handlers, list) {
2438 if (ec_eoe_is_open(eoe))
2440 }
2441#endif
2442
2443 master->app_time = 0ULL;
2444 master->dc_ref_time = 0ULL;
2445
2446#ifdef EC_EOE
2447 if (eoe_was_running) {
2448 ec_master_eoe_start(master);
2449 }
2450#endif
2452 "EtherCAT-IDLE")) {
2453 EC_MASTER_WARN(master, "Failed to restart master thread!\n");
2454 }
2455
2456 /* Disallow scanning to get into the same state like after a master
2457 * request (after ec_master_enter_operation_phase() is called). */
2458 master->allow_scan = 0;
2459
2460 master->active = 0;
2461}
2462
2463/*****************************************************************************/
2464
2466{
2467 ec_datagram_t *datagram, *n;
2468 ec_device_index_t dev_idx;
2469
2470 if (master->injection_seq_rt != master->injection_seq_fsm) {
2471 // inject datagram produced by master FSM
2472 ec_master_queue_datagram(master, &master->fsm_datagram);
2473 master->injection_seq_rt = master->injection_seq_fsm;
2474 }
2475
2477
2478 for (dev_idx = EC_DEVICE_MAIN; dev_idx < ec_master_num_devices(master);
2479 dev_idx++) {
2480 if (unlikely(!master->devices[dev_idx].link_state)) {
2481 // link is down, no datagram can be sent
2482 list_for_each_entry_safe(datagram, n,
2483 &master->datagram_queue, queue) {
2484 if (datagram->device_index == dev_idx) {
2485 datagram->state = EC_DATAGRAM_ERROR;
2486 list_del_init(&datagram->queue);
2487 }
2488 }
2489
2490 if (!master->devices[dev_idx].dev) {
2491 continue;
2492 }
2493
2494 // query link state
2495 ec_device_poll(&master->devices[dev_idx]);
2496
2497 // clear frame statistics
2498 ec_device_clear_stats(&master->devices[dev_idx]);
2499 continue;
2500 }
2501
2502 // send frames
2503 ec_master_send_datagrams(master, dev_idx);
2504 }
2505}
2506
2507/*****************************************************************************/
2508
2510{
2511 unsigned int dev_idx;
2512 ec_datagram_t *datagram, *next;
2513
2514 // receive datagrams
2515 for (dev_idx = EC_DEVICE_MAIN; dev_idx < ec_master_num_devices(master);
2516 dev_idx++) {
2517 ec_device_poll(&master->devices[dev_idx]);
2518 }
2520
2521 // dequeue all datagrams that timed out
2522 list_for_each_entry_safe(datagram, next, &master->datagram_queue, queue) {
2523 if (datagram->state != EC_DATAGRAM_SENT) continue;
2524
2525#ifdef EC_HAVE_CYCLES
2526 if (master->devices[EC_DEVICE_MAIN].cycles_poll -
2527 datagram->cycles_sent > timeout_cycles) {
2528#else
2529 if (master->devices[EC_DEVICE_MAIN].jiffies_poll -
2530 datagram->jiffies_sent > timeout_jiffies) {
2531#endif
2532 list_del_init(&datagram->queue);
2533 datagram->state = EC_DATAGRAM_TIMED_OUT;
2534 master->stats.timeouts++;
2535
2536#ifdef EC_RT_SYSLOG
2537 ec_master_output_stats(master);
2538
2539 if (unlikely(master->debug_level > 0)) {
2540 unsigned int time_us;
2541#ifdef EC_HAVE_CYCLES
2542 time_us = (unsigned int)
2543 (master->devices[EC_DEVICE_MAIN].cycles_poll -
2544 datagram->cycles_sent) * 1000 / cpu_khz;
2545#else
2546 time_us = (unsigned int)
2548 datagram->jiffies_sent) * 1000000 / HZ);
2549#endif
2550 EC_MASTER_DBG(master, 0, "TIMED OUT datagram %p,"
2551 " index %02X waited %u us.\n",
2552 datagram, datagram->index, time_us);
2553 }
2554#endif /* RT_SYSLOG */
2555 }
2556 }
2557}
2558
2559/*****************************************************************************/
2560
2562{
2563 ec_datagram_t *datagram, *next;
2564
2565 list_for_each_entry_safe(datagram, next, &master->ext_datagram_queue,
2566 queue) {
2567 list_del(&datagram->queue);
2568 ec_master_queue_datagram(master, datagram);
2569 }
2570
2571 ecrt_master_send(master);
2572}
2573
2574/*****************************************************************************/
2575
2579 uint16_t alias, uint16_t position, uint32_t vendor_id,
2580 uint32_t product_code)
2581{
2583 unsigned int found = 0;
2584
2585
2586 EC_MASTER_DBG(master, 1, "ecrt_master_slave_config(master = 0x%p,"
2587 " alias = %u, position = %u, vendor_id = 0x%08x,"
2588 " product_code = 0x%08x)\n",
2589 master, alias, position, vendor_id, product_code);
2590
2591 list_for_each_entry(sc, &master->configs, list) {
2592 if (sc->alias == alias && sc->position == position) {
2593 found = 1;
2594 break;
2595 }
2596 }
2597
2598 if (found) { // config with same alias/position already existing
2599 if (sc->vendor_id != vendor_id || sc->product_code != product_code) {
2600 EC_MASTER_ERR(master, "Slave type mismatch. Slave was"
2601 " configured as 0x%08X/0x%08X before. Now configuring"
2602 " with 0x%08X/0x%08X.\n", sc->vendor_id, sc->product_code,
2603 vendor_id, product_code);
2604 return ERR_PTR(-ENOENT);
2605 }
2606 } else {
2607 EC_MASTER_DBG(master, 1, "Creating slave configuration for %u:%u,"
2608 " 0x%08X/0x%08X.\n",
2609 alias, position, vendor_id, product_code);
2610
2611 if (!(sc = (ec_slave_config_t *) kmalloc(sizeof(ec_slave_config_t),
2612 GFP_KERNEL))) {
2613 EC_MASTER_ERR(master, "Failed to allocate memory"
2614 " for slave configuration.\n");
2615 return ERR_PTR(-ENOMEM);
2616 }
2617
2618 ec_slave_config_init(sc, master,
2619 alias, position, vendor_id, product_code);
2620
2621 down(&master->master_sem);
2622
2623 // try to find the addressed slave
2626 list_add_tail(&sc->list, &master->configs);
2627
2628 up(&master->master_sem);
2629 }
2630
2631 return sc;
2632}
2633
2634/*****************************************************************************/
2635
2637 uint16_t alias, uint16_t position, uint32_t vendor_id,
2638 uint32_t product_code)
2639{
2641 position, vendor_id, product_code);
2642 return IS_ERR(sc) ? NULL : sc;
2643}
2644
2645/*****************************************************************************/
2646
2649{
2650 if (sc) {
2651 ec_slave_t *slave = sc->slave;
2652
2653 // output an early warning
2654 if (slave &&
2655 (!slave->base_dc_supported || !slave->has_dc_system_time)) {
2656 EC_MASTER_WARN(master, "Slave %u can not act as"
2657 " a reference clock!", slave->ring_position);
2658 }
2659 }
2660
2661 master->dc_ref_config = sc;
2662 return 0;
2663}
2664
2665/*****************************************************************************/
2666
2667int ecrt_master(ec_master_t *master, ec_master_info_t *master_info)
2668{
2669 EC_MASTER_DBG(master, 1, "ecrt_master(master = 0x%p,"
2670 " master_info = 0x%p)\n", master, master_info);
2671
2672 master_info->slave_count = master->slave_count;
2673 master_info->link_up = master->devices[EC_DEVICE_MAIN].link_state;
2674 master_info->scan_busy = master->scan_busy;
2675 master_info->app_time = master->app_time;
2676 return 0;
2677}
2678
2679/*****************************************************************************/
2680
2681int ecrt_master_get_slave(ec_master_t *master, uint16_t slave_position,
2682 ec_slave_info_t *slave_info)
2683{
2684 const ec_slave_t *slave;
2685 unsigned int i;
2686 int ret = 0;
2687
2688 if (down_interruptible(&master->master_sem)) {
2689 return -EINTR;
2690 }
2691
2692 slave = ec_master_find_slave_const(master, 0, slave_position);
2693
2694 if (slave == NULL) {
2695 ret = -ENOENT;
2696 goto out_get_slave;
2697 }
2698
2699 slave_info->position = slave->ring_position;
2700 slave_info->vendor_id = slave->sii.vendor_id;
2701 slave_info->product_code = slave->sii.product_code;
2702 slave_info->revision_number = slave->sii.revision_number;
2703 slave_info->serial_number = slave->sii.serial_number;
2704 slave_info->alias = slave->effective_alias;
2705 slave_info->current_on_ebus = slave->sii.current_on_ebus;
2706
2707 for (i = 0; i < EC_MAX_PORTS; i++) {
2708 slave_info->ports[i].desc = slave->ports[i].desc;
2709 slave_info->ports[i].link.link_up = slave->ports[i].link.link_up;
2710 slave_info->ports[i].link.loop_closed =
2711 slave->ports[i].link.loop_closed;
2712 slave_info->ports[i].link.signal_detected =
2713 slave->ports[i].link.signal_detected;
2714 slave_info->ports[i].receive_time = slave->ports[i].receive_time;
2715 if (slave->ports[i].next_slave) {
2716 slave_info->ports[i].next_slave =
2717 slave->ports[i].next_slave->ring_position;
2718 } else {
2719 slave_info->ports[i].next_slave = 0xffff;
2720 }
2721 slave_info->ports[i].delay_to_next_dc =
2722 slave->ports[i].delay_to_next_dc;
2723 }
2724
2725 slave_info->al_state = slave->current_state;
2726 slave_info->error_flag = slave->error_flag;
2727 slave_info->sync_count = slave->sii.sync_count;
2728 slave_info->sdo_count = ec_slave_sdo_count(slave);
2729 if (slave->sii.name) {
2730 strncpy(slave_info->name, slave->sii.name, EC_MAX_STRING_LENGTH);
2731 } else {
2732 slave_info->name[0] = 0;
2733 }
2734
2735out_get_slave:
2736 up(&master->master_sem);
2737
2738 return ret;
2739}
2740
2741/*****************************************************************************/
2742
2744 void (*send_cb)(void *), void (*receive_cb)(void *), void *cb_data)
2745{
2746 EC_MASTER_DBG(master, 1, "ecrt_master_callbacks(master = 0x%p,"
2747 " send_cb = 0x%p, receive_cb = 0x%p, cb_data = 0x%p)\n",
2748 master, send_cb, receive_cb, cb_data);
2749
2750 master->app_send_cb = send_cb;
2751 master->app_receive_cb = receive_cb;
2752 master->app_cb_data = cb_data;
2753}
2754
2755/*****************************************************************************/
2756
2758{
2759 ec_device_index_t dev_idx;
2760
2761 state->slaves_responding = 0U;
2762 state->al_states = 0;
2763 state->link_up = 0U;
2764
2765 for (dev_idx = EC_DEVICE_MAIN; dev_idx < ec_master_num_devices(master);
2766 dev_idx++) {
2767 /* Announce sum of responding slaves on all links. */
2768 state->slaves_responding += master->fsm.slaves_responding[dev_idx];
2769
2770 /* Binary-or slave states of all links. */
2771 state->al_states |= master->fsm.slave_states[dev_idx];
2772
2773 /* Signal link up if at least one device has link. */
2774 state->link_up |= master->devices[dev_idx].link_state;
2775 }
2776}
2777
2778/*****************************************************************************/
2779
2780int ecrt_master_link_state(const ec_master_t *master, unsigned int dev_idx,
2782{
2783 if (dev_idx >= ec_master_num_devices(master)) {
2784 return -EINVAL;
2785 }
2786
2787 state->slaves_responding = master->fsm.slaves_responding[dev_idx];
2788 state->al_states = master->fsm.slave_states[dev_idx];
2789 state->link_up = master->devices[dev_idx].link_state;
2790
2791 return 0;
2792}
2793
2794/*****************************************************************************/
2795
2796void ecrt_master_application_time(ec_master_t *master, uint64_t app_time)
2797{
2798 master->app_time = app_time;
2799
2800 if (unlikely(!master->dc_ref_time)) {
2801 master->dc_ref_time = app_time;
2802 }
2803}
2804
2805/*****************************************************************************/
2806
2808{
2809 if (!master->dc_ref_clock) {
2810 return -ENXIO;
2811 }
2812
2813 if (master->sync_datagram.state != EC_DATAGRAM_RECEIVED) {
2814 return -EIO;
2815 }
2816
2817 // Get returned datagram time, transmission delay removed.
2818 *time = EC_READ_U32(master->sync_datagram.data) -
2820
2821 return 0;
2822}
2823
2824/*****************************************************************************/
2825
2827{
2828 if (master->dc_ref_clock) {
2829 EC_WRITE_U32(master->ref_sync_datagram.data, master->app_time);
2831 }
2832}
2833
2834/*****************************************************************************/
2835
2837 ec_master_t *master,
2838 uint64_t sync_time
2839 )
2840{
2841 if (master->dc_ref_clock) {
2842 EC_WRITE_U32(master->ref_sync_datagram.data, sync_time);
2844 }
2845}
2846
2847/*****************************************************************************/
2848
2850{
2851 if (master->dc_ref_clock) {
2853 ec_master_queue_datagram(master, &master->sync_datagram);
2854 }
2855}
2856
2857/*****************************************************************************/
2858
2860{
2863}
2864
2865/*****************************************************************************/
2866
2868{
2870 return EC_READ_U32(master->sync_mon_datagram.data) & 0x7fffffff;
2871 } else {
2872 return 0xffffffff;
2873 }
2874}
2875
2876/*****************************************************************************/
2877
2878int ecrt_master_sdo_download(ec_master_t *master, uint16_t slave_position,
2879 uint16_t index, uint8_t subindex, uint8_t *data,
2880 size_t data_size, uint32_t *abort_code)
2881{
2882 ec_sdo_request_t request;
2883 ec_slave_t *slave;
2884 int ret;
2885
2886 EC_MASTER_DBG(master, 1, "%s(master = 0x%p,"
2887 " slave_position = %u, index = 0x%04X, subindex = 0x%02X,"
2888 " data = 0x%p, data_size = %zu, abort_code = 0x%p)\n",
2889 __func__, master, slave_position, index, subindex,
2890 data, data_size, abort_code);
2891
2892 ec_sdo_request_init(&request);
2893 ecrt_sdo_request_index(&request, index, subindex);
2894 ret = ec_sdo_request_alloc(&request, data_size);
2895 if (ret) {
2896 ec_sdo_request_clear(&request);
2897 return ret;
2898 }
2899
2900 memcpy(request.data, data, data_size);
2901 request.data_size = data_size;
2902 ecrt_sdo_request_write(&request);
2903
2904 if (down_interruptible(&master->master_sem)) {
2905 ec_sdo_request_clear(&request);
2906 return -EINTR;
2907 }
2908
2909 if (!(slave = ec_master_find_slave(master, 0, slave_position))) {
2910 up(&master->master_sem);
2911 EC_MASTER_ERR(master, "Slave %u does not exist!\n", slave_position);
2912 ec_sdo_request_clear(&request);
2913 return -EINVAL;
2914 }
2915
2916 EC_SLAVE_DBG(slave, 1, "Scheduling SDO download request.\n");
2917
2918 // schedule request.
2919 list_add_tail(&request.list, &slave->sdo_requests);
2920
2921 up(&master->master_sem);
2922
2923 // wait for processing through FSM
2924 if (wait_event_interruptible(master->request_queue,
2925 request.state != EC_INT_REQUEST_QUEUED)) {
2926 // interrupted by signal
2927 down(&master->master_sem);
2928 if (request.state == EC_INT_REQUEST_QUEUED) {
2929 list_del(&request.list);
2930 up(&master->master_sem);
2931 ec_sdo_request_clear(&request);
2932 return -EINTR;
2933 }
2934 // request already processing: interrupt not possible.
2935 up(&master->master_sem);
2936 }
2937
2938 // wait until master FSM has finished processing
2939 wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
2940
2941 *abort_code = request.abort_code;
2942
2943 if (request.state == EC_INT_REQUEST_SUCCESS) {
2944 ret = 0;
2945 } else if (request.errno) {
2946 ret = -request.errno;
2947 } else {
2948 ret = -EIO;
2949 }
2950
2951 ec_sdo_request_clear(&request);
2952 return ret;
2953}
2954
2955/*****************************************************************************/
2956
2958 uint16_t slave_position, uint16_t index, uint8_t *data,
2959 size_t data_size, uint32_t *abort_code)
2960{
2961 ec_sdo_request_t request;
2962 ec_slave_t *slave;
2963 int ret;
2964
2965 EC_MASTER_DBG(master, 1, "%s(master = 0x%p,"
2966 " slave_position = %u, index = 0x%04X,"
2967 " data = 0x%p, data_size = %zu, abort_code = 0x%p)\n",
2968 __func__, master, slave_position, index, data, data_size,
2969 abort_code);
2970
2971 ec_sdo_request_init(&request);
2972 ecrt_sdo_request_index(&request, index, 0);
2973 ret = ec_sdo_request_alloc(&request, data_size);
2974 if (ret) {
2975 ec_sdo_request_clear(&request);
2976 return ret;
2977 }
2978
2979 request.complete_access = 1;
2980 memcpy(request.data, data, data_size);
2981 request.data_size = data_size;
2982 ecrt_sdo_request_write(&request);
2983
2984 if (down_interruptible(&master->master_sem)) {
2985 ec_sdo_request_clear(&request);
2986 return -EINTR;
2987 }
2988
2989 if (!(slave = ec_master_find_slave(master, 0, slave_position))) {
2990 up(&master->master_sem);
2991 EC_MASTER_ERR(master, "Slave %u does not exist!\n", slave_position);
2992 ec_sdo_request_clear(&request);
2993 return -EINVAL;
2994 }
2995
2996 EC_SLAVE_DBG(slave, 1, "Scheduling SDO download request"
2997 " (complete access).\n");
2998
2999 // schedule request.
3000 list_add_tail(&request.list, &slave->sdo_requests);
3001
3002 up(&master->master_sem);
3003
3004 // wait for processing through FSM
3005 if (wait_event_interruptible(master->request_queue,
3006 request.state != EC_INT_REQUEST_QUEUED)) {
3007 // interrupted by signal
3008 down(&master->master_sem);
3009 if (request.state == EC_INT_REQUEST_QUEUED) {
3010 list_del(&request.list);
3011 up(&master->master_sem);
3012 ec_sdo_request_clear(&request);
3013 return -EINTR;
3014 }
3015 // request already processing: interrupt not possible.
3016 up(&master->master_sem);
3017 }
3018
3019 // wait until master FSM has finished processing
3020 wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
3021
3022 *abort_code = request.abort_code;
3023
3024 if (request.state == EC_INT_REQUEST_SUCCESS) {
3025 ret = 0;
3026 } else if (request.errno) {
3027 ret = -request.errno;
3028 } else {
3029 ret = -EIO;
3030 }
3031
3032 ec_sdo_request_clear(&request);
3033 return ret;
3034}
3035
3036/*****************************************************************************/
3037
3038int ecrt_master_sdo_upload(ec_master_t *master, uint16_t slave_position,
3039 uint16_t index, uint8_t subindex, uint8_t *target,
3040 size_t target_size, size_t *result_size, uint32_t *abort_code)
3041{
3042 ec_sdo_request_t request;
3043 ec_slave_t *slave;
3044 int ret = 0;
3045
3046 EC_MASTER_DBG(master, 1, "%s(master = 0x%p,"
3047 " slave_position = %u, index = 0x%04X, subindex = 0x%02X,"
3048 " target = 0x%p, target_size = %zu, result_size = 0x%p,"
3049 " abort_code = 0x%p)\n",
3050 __func__, master, slave_position, index, subindex,
3051 target, target_size, result_size, abort_code);
3052
3053 ec_sdo_request_init(&request);
3054 ecrt_sdo_request_index(&request, index, subindex);
3055 ecrt_sdo_request_read(&request);
3056
3057 if (down_interruptible(&master->master_sem)) {
3058 ec_sdo_request_clear(&request);
3059 return -EINTR;
3060 }
3061
3062 if (!(slave = ec_master_find_slave(master, 0, slave_position))) {
3063 up(&master->master_sem);
3064 ec_sdo_request_clear(&request);
3065 EC_MASTER_ERR(master, "Slave %u does not exist!\n", slave_position);
3066 return -EINVAL;
3067 }
3068
3069 EC_SLAVE_DBG(slave, 1, "Scheduling SDO upload request.\n");
3070
3071 // schedule request.
3072 list_add_tail(&request.list, &slave->sdo_requests);
3073
3074 up(&master->master_sem);
3075
3076 // wait for processing through FSM
3077 if (wait_event_interruptible(master->request_queue,
3078 request.state != EC_INT_REQUEST_QUEUED)) {
3079 // interrupted by signal
3080 down(&master->master_sem);
3081 if (request.state == EC_INT_REQUEST_QUEUED) {
3082 list_del(&request.list);
3083 up(&master->master_sem);
3084 ec_sdo_request_clear(&request);
3085 return -EINTR;
3086 }
3087 // request already processing: interrupt not possible.
3088 up(&master->master_sem);
3089 }
3090
3091 // wait until master FSM has finished processing
3092 wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
3093
3094 *abort_code = request.abort_code;
3095
3096 if (request.state != EC_INT_REQUEST_SUCCESS) {
3097 *result_size = 0;
3098 if (request.errno) {
3099 ret = -request.errno;
3100 } else {
3101 ret = -EIO;
3102 }
3103 } else {
3104 if (request.data_size > target_size) {
3105 EC_SLAVE_ERR(slave, "%s(): Buffer too small.\n", __func__);
3106 ret = -EOVERFLOW;
3107 }
3108 else {
3109 memcpy(target, request.data, request.data_size);
3110 *result_size = request.data_size;
3111 ret = 0;
3112 }
3113 }
3114
3115 ec_sdo_request_clear(&request);
3116 return ret;
3117}
3118
3119/*****************************************************************************/
3120
3121int ecrt_master_write_idn(ec_master_t *master, uint16_t slave_position,
3122 uint8_t drive_no, uint16_t idn, uint8_t *data, size_t data_size,
3123 uint16_t *error_code)
3124{
3125 ec_soe_request_t request;
3126 ec_slave_t *slave;
3127 int ret;
3128
3129 if (drive_no > 7) {
3130 EC_MASTER_ERR(master, "Invalid drive number!\n");
3131 return -EINVAL;
3132 }
3133
3134 ec_soe_request_init(&request);
3135 ec_soe_request_set_drive_no(&request, drive_no);
3136 ec_soe_request_set_idn(&request, idn);
3137
3138 ret = ec_soe_request_alloc(&request, data_size);
3139 if (ret) {
3140 ec_soe_request_clear(&request);
3141 return ret;
3142 }
3143
3144 memcpy(request.data, data, data_size);
3145 request.data_size = data_size;
3146 ec_soe_request_write(&request);
3147
3148 if (down_interruptible(&master->master_sem)) {
3149 ec_soe_request_clear(&request);
3150 return -EINTR;
3151 }
3152
3153 if (!(slave = ec_master_find_slave(master, 0, slave_position))) {
3154 up(&master->master_sem);
3155 EC_MASTER_ERR(master, "Slave %u does not exist!\n",
3156 slave_position);
3157 ec_soe_request_clear(&request);
3158 return -EINVAL;
3159 }
3160
3161 EC_SLAVE_DBG(slave, 1, "Scheduling SoE write request.\n");
3162
3163 // schedule SoE write request.
3164 list_add_tail(&request.list, &slave->soe_requests);
3165
3166 up(&master->master_sem);
3167
3168 // wait for processing through FSM
3169 if (wait_event_interruptible(master->request_queue,
3170 request.state != EC_INT_REQUEST_QUEUED)) {
3171 // interrupted by signal
3172 down(&master->master_sem);
3173 if (request.state == EC_INT_REQUEST_QUEUED) {
3174 // abort request
3175 list_del(&request.list);
3176 up(&master->master_sem);
3177 ec_soe_request_clear(&request);
3178 return -EINTR;
3179 }
3180 up(&master->master_sem);
3181 }
3182
3183 // wait until master FSM has finished processing
3184 wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
3185
3186 if (error_code) {
3187 *error_code = request.error_code;
3188 }
3189 ret = request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
3190 ec_soe_request_clear(&request);
3191
3192 return ret;
3193}
3194
3195/*****************************************************************************/
3196
3197int ecrt_master_read_idn(ec_master_t *master, uint16_t slave_position,
3198 uint8_t drive_no, uint16_t idn, uint8_t *target, size_t target_size,
3199 size_t *result_size, uint16_t *error_code)
3200{
3201 ec_soe_request_t request;
3202 ec_slave_t *slave;
3203 int ret;
3204
3205 if (drive_no > 7) {
3206 EC_MASTER_ERR(master, "Invalid drive number!\n");
3207 return -EINVAL;
3208 }
3209
3210 ec_soe_request_init(&request);
3211 ec_soe_request_set_drive_no(&request, drive_no);
3212 ec_soe_request_set_idn(&request, idn);
3213 ec_soe_request_read(&request);
3214
3215 if (down_interruptible(&master->master_sem)) {
3216 ec_soe_request_clear(&request);
3217 return -EINTR;
3218 }
3219
3220 if (!(slave = ec_master_find_slave(master, 0, slave_position))) {
3221 up(&master->master_sem);
3222 ec_soe_request_clear(&request);
3223 EC_MASTER_ERR(master, "Slave %u does not exist!\n", slave_position);
3224 return -EINVAL;
3225 }
3226
3227 EC_SLAVE_DBG(slave, 1, "Scheduling SoE read request.\n");
3228
3229 // schedule request.
3230 list_add_tail(&request.list, &slave->soe_requests);
3231
3232 up(&master->master_sem);
3233
3234 // wait for processing through FSM
3235 if (wait_event_interruptible(master->request_queue,
3236 request.state != EC_INT_REQUEST_QUEUED)) {
3237 // interrupted by signal
3238 down(&master->master_sem);
3239 if (request.state == EC_INT_REQUEST_QUEUED) {
3240 list_del(&request.list);
3241 up(&master->master_sem);
3242 ec_soe_request_clear(&request);
3243 return -EINTR;
3244 }
3245 // request already processing: interrupt not possible.
3246 up(&master->master_sem);
3247 }
3248
3249 // wait until master FSM has finished processing
3250 wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
3251
3252 if (error_code) {
3253 *error_code = request.error_code;
3254 }
3255
3256 if (request.state != EC_INT_REQUEST_SUCCESS) {
3257 if (result_size) {
3258 *result_size = 0;
3259 }
3260 ret = -EIO;
3261 } else { // success
3262 if (request.data_size > target_size) {
3263 EC_SLAVE_ERR(slave, "%s(): Buffer too small.\n", __func__);
3264 ret = -EOVERFLOW;
3265 }
3266 else { // data fits in buffer
3267 if (result_size) {
3268 *result_size = request.data_size;
3269 }
3270 memcpy(target, request.data, request.data_size);
3271 ret = 0;
3272 }
3273 }
3274
3275 ec_soe_request_clear(&request);
3276 return ret;
3277}
3278
3279/*****************************************************************************/
3280
3282{
3284
3285 list_for_each_entry(sc, &master->configs, list) {
3286 if (sc->slave) {
3288 }
3289 }
3290}
3291
3292/*****************************************************************************/
3293
3296EXPORT_SYMBOL(ecrt_master_create_domain);
3297EXPORT_SYMBOL(ecrt_master_activate);
3298EXPORT_SYMBOL(ecrt_master_deactivate);
3299EXPORT_SYMBOL(ecrt_master_send);
3300EXPORT_SYMBOL(ecrt_master_send_ext);
3301EXPORT_SYMBOL(ecrt_master_receive);
3302EXPORT_SYMBOL(ecrt_master_callbacks);
3303EXPORT_SYMBOL(ecrt_master);
3304EXPORT_SYMBOL(ecrt_master_get_slave);
3305EXPORT_SYMBOL(ecrt_master_slave_config);
3307EXPORT_SYMBOL(ecrt_master_state);
3308EXPORT_SYMBOL(ecrt_master_link_state);
3309EXPORT_SYMBOL(ecrt_master_application_time);
3312EXPORT_SYMBOL(ecrt_master_sync_slave_clocks);
3314EXPORT_SYMBOL(ecrt_master_sync_monitor_queue);
3316EXPORT_SYMBOL(ecrt_master_sdo_download);
3318EXPORT_SYMBOL(ecrt_master_sdo_upload);
3319EXPORT_SYMBOL(ecrt_master_write_idn);
3320EXPORT_SYMBOL(ecrt_master_read_idn);
3321EXPORT_SYMBOL(ecrt_master_reset);
3322
3325/*****************************************************************************/
int ec_cdev_init(ec_cdev_t *cdev, ec_master_t *master, dev_t dev_num)
Constructor.
Definition: cdev.c:116
void ec_cdev_clear(ec_cdev_t *cdev)
Destructor.
Definition: cdev.c:142
int ec_datagram_frmw(ec_datagram_t *datagram, uint16_t configured_address, uint16_t mem_address, size_t data_size)
Initializes an EtherCAT FRMW datagram.
Definition: datagram.c:348
int ec_datagram_prealloc(ec_datagram_t *datagram, size_t size)
Allocates internal payload memory.
Definition: datagram.c:150
void ec_datagram_zero(ec_datagram_t *datagram)
Fills the datagram payload memory with zeros.
Definition: datagram.c:178
int ec_datagram_brd(ec_datagram_t *datagram, uint16_t mem_address, size_t data_size)
Initializes an EtherCAT BRD datagram.
Definition: datagram.c:373
void ec_datagram_output_stats(ec_datagram_t *datagram)
Outputs datagram statistics at most every second.
Definition: datagram.c:622
void ec_datagram_clear(ec_datagram_t *datagram)
Destructor.
Definition: datagram.c:118
int ec_datagram_fpwr(ec_datagram_t *datagram, uint16_t configured_address, uint16_t mem_address, size_t data_size)
Initializes an EtherCAT FPWR datagram.
Definition: datagram.c:298
void ec_datagram_init(ec_datagram_t *datagram)
Constructor.
Definition: datagram.c:88
EtherCAT datagram structure.
@ EC_DATAGRAM_FPWR
Configured Address Physical Write.
Definition: datagram.h:56
@ EC_DATAGRAM_LWR
Logical Write.
Definition: datagram.h:62
@ EC_DATAGRAM_BWR
Broadcast Write.
Definition: datagram.h:59
@ EC_DATAGRAM_APWR
Auto Increment Physical Write.
Definition: datagram.h:53
@ EC_DATAGRAM_INIT
Initial state of a new datagram.
Definition: datagram.h:75
@ EC_DATAGRAM_RECEIVED
Received (dequeued).
Definition: datagram.h:78
@ EC_DATAGRAM_TIMED_OUT
Timed out (dequeued).
Definition: datagram.h:79
@ EC_DATAGRAM_SENT
Sent (still in the queue).
Definition: datagram.h:77
@ EC_DATAGRAM_QUEUED
Queued for sending.
Definition: datagram.h:76
@ EC_DATAGRAM_ERROR
Error while sending/receiving (dequeued).
Definition: datagram.h:80
void ec_device_update_stats(ec_device_t *device)
Update device statistics.
Definition: device.c:496
int ec_device_init(ec_device_t *device, ec_master_t *master)
Constructor.
Definition: device.c:63
uint8_t * ec_device_tx_data(ec_device_t *device)
Returns a pointer to the device's transmit memory.
Definition: device.c:312
void ec_device_poll(ec_device_t *device)
Calls the poll function of the assigned net_device.
Definition: device.c:478
void ec_device_clear_stats(ec_device_t *device)
Clears the frame statistics.
Definition: device.c:374
void ec_device_clear(ec_device_t *device)
Destructor.
Definition: device.c:162
void ec_device_send(ec_device_t *device, size_t size)
Sends the content of the transmit socket buffer.
Definition: device.c:331
EtherCAT device structure.
int ec_domain_finish(ec_domain_t *domain, uint32_t base_address)
Finishes a domain.
Definition: domain.c:226
void ec_domain_init(ec_domain_t *domain, ec_master_t *master, unsigned int index)
Domain constructor.
Definition: domain.c:58
void ec_domain_clear(ec_domain_t *domain)
Domain destructor.
Definition: domain.c:88
int ec_eoe_is_open(const ec_eoe_t *eoe)
Returns the state of the device.
Definition: ethernet.c:383
void ec_eoe_run(ec_eoe_t *eoe)
Runs the EoE state machine.
Definition: ethernet.c:341
void ec_eoe_clear(ec_eoe_t *eoe)
EoE destructor.
Definition: ethernet.c:224
void ec_eoe_queue(ec_eoe_t *eoe)
Queues the datagram, if necessary.
Definition: ethernet.c:369
int ec_eoe_is_idle(const ec_eoe_t *eoe)
Returns the idle state.
Definition: ethernet.c:395
Ethernet over EtherCAT (EoE)
int ec_fsm_master_exec(ec_fsm_master_t *fsm)
Executes the current state of the state machine.
Definition: fsm_master.c:151
void ec_fsm_master_init(ec_fsm_master_t *fsm, ec_master_t *master, ec_datagram_t *datagram)
Constructor.
Definition: fsm_master.c:77
int ec_fsm_master_idle(const ec_fsm_master_t *fsm)
Definition: fsm_master.c:170
void ec_fsm_master_clear(ec_fsm_master_t *fsm)
Destructor.
Definition: fsm_master.c:104
void ec_fsm_master_reset(ec_fsm_master_t *fsm)
Reset state machine.
Definition: fsm_master.c:122
int ec_fsm_slave_exec(ec_fsm_slave_t *fsm, ec_datagram_t *datagram)
Executes the current state of the state machine.
Definition: fsm_slave.c:123
int ec_fsm_slave_is_ready(const ec_fsm_slave_t *fsm)
Returns, if the FSM is currently not busy and ready to execute.
Definition: fsm_slave.c:164
Global definitions and macros.
#define EC_RATE_COUNT
Number of statistic rate intervals to maintain.
Definition: globals.h:60
#define EC_BYTE_TRANSMISSION_TIME_NS
Time to send a byte in nanoseconds.
Definition: globals.h:44
@ EC_SLAVE_STATE_PREOP
PREOP state (mailbox communication, no IO)
Definition: globals.h:120
@ EC_SLAVE_STATE_OP
OP (mailbox communication and input/output update)
Definition: globals.h:126
#define EC_MAX_DATA_SIZE
Resulting maximum data size of a single datagram in a frame.
Definition: globals.h:79
int ec_mac_is_zero(const uint8_t *)
Definition: module.c:270
#define EC_IO_TIMEOUT
Datagram timeout in microseconds.
Definition: globals.h:38
#define EC_FRAME_HEADER_SIZE
Size of an EtherCAT frame header.
Definition: globals.h:67
#define EC_ADDR_LEN
Size of the EtherCAT address field.
Definition: globals.h:76
#define EC_DATAGRAM_HEADER_SIZE
Size of an EtherCAT datagram header.
Definition: globals.h:70
#define EC_DATAGRAM_FOOTER_SIZE
Size of an EtherCAT datagram footer.
Definition: globals.h:73
#define EC_DATAGRAM_NAME_SIZE
Size of the datagram description string.
Definition: globals.h:104
ec_device_index_t
Master devices.
Definition: globals.h:189
@ EC_DEVICE_MAIN
Main device.
Definition: globals.h:190
@ EC_DEVICE_BACKUP
Backup device.
Definition: globals.h:191
void ec_print_data(const uint8_t *, size_t)
Outputs frame contents for debugging purposes.
Definition: module.c:348
uint32_t ecrt_master_sync_monitor_process(ec_master_t *master)
Processes the DC synchrony monitoring datagram.
Definition: master.c:2867
ec_slave_config_t * ecrt_master_slave_config(ec_master_t *master, uint16_t alias, uint16_t position, uint32_t vendor_id, uint32_t product_code)
Obtains a slave configuration.
Definition: master.c:2636
#define EC_MAX_PORTS
Maximum number of slave ports.
Definition: ecrt.h:222
int ecrt_master_select_reference_clock(ec_master_t *master, ec_slave_config_t *sc)
Selects the reference clock for distributed clocks.
Definition: master.c:2647
int ecrt_master_sdo_download_complete(ec_master_t *master, uint16_t slave_position, uint16_t index, uint8_t *data, size_t data_size, uint32_t *abort_code)
Executes an SDO download request to write data to a slave via complete access.
Definition: master.c:2957
void ecrt_master_sync_monitor_queue(ec_master_t *master)
Queues the DC synchrony monitoring datagram for sending.
Definition: master.c:2859
#define EC_WRITE_U8(DATA, VAL)
Write an 8-bit unsigned value to EtherCAT data.
Definition: ecrt.h:2266
void ecrt_master_send(ec_master_t *master)
Sends all datagrams in the queue.
Definition: master.c:2465
void ecrt_master_deactivate(ec_master_t *master)
Deactivates the master.
Definition: master.c:2395
int ecrt_master_sdo_download(ec_master_t *master, uint16_t slave_position, uint16_t index, uint8_t subindex, uint8_t *data, size_t data_size, uint32_t *abort_code)
Executes an SDO download request to write data to a slave.
Definition: master.c:2878
void ecrt_master_application_time(ec_master_t *master, uint64_t app_time)
Sets the application time.
Definition: master.c:2796
int ecrt_master_write_idn(ec_master_t *master, uint16_t slave_position, uint8_t drive_no, uint16_t idn, uint8_t *data, size_t data_size, uint16_t *error_code)
Executes an SoE write request.
Definition: master.c:3121
void ecrt_master_send_ext(ec_master_t *master)
Sends non-application datagrams.
Definition: master.c:2561
void ecrt_master_callbacks(ec_master_t *master, void(*send_cb)(void *), void(*receive_cb)(void *), void *cb_data)
Sets the locking callbacks.
Definition: master.c:2743
void ecrt_sdo_request_read(ec_sdo_request_t *req)
Schedule an SDO read operation.
Definition: sdo_request.c:224
int ecrt_master_get_slave(ec_master_t *master, uint16_t slave_position, ec_slave_info_t *slave_info)
Obtains slave information.
Definition: master.c:2681
int ecrt_master_sdo_upload(ec_master_t *master, uint16_t slave_position, uint16_t index, uint8_t subindex, uint8_t *target, size_t target_size, size_t *result_size, uint32_t *abort_code)
Executes an SDO upload request to read data from a slave.
Definition: master.c:3038
int ecrt_master_link_state(const ec_master_t *master, unsigned int dev_idx, ec_master_link_state_t *state)
Reads the current state of a redundant link.
Definition: master.c:2780
void ecrt_master_receive(ec_master_t *master)
Fetches received frames from the hardware and processes the datagrams.
Definition: master.c:2509
#define EC_WRITE_U32(DATA, VAL)
Write a 32-bit unsigned value to EtherCAT data.
Definition: ecrt.h:2300
ec_domain_t * ecrt_master_create_domain(ec_master_t *master)
Creates a new process data domain.
Definition: master.c:2311
void ecrt_master_state(const ec_master_t *master, ec_master_state_t *state)
Reads the current master state.
Definition: master.c:2757
int ecrt_master_activate(ec_master_t *master)
Finishes the configuration phase and prepares for cyclic operation.
Definition: master.c:2321
#define EC_READ_U16(DATA)
Read a 16-bit unsigned value from EtherCAT data.
Definition: ecrt.h:2178
void ecrt_master_sync_reference_clock_to(ec_master_t *master, uint64_t sync_time)
Queues the DC reference clock drift compensation datagram for sending.
Definition: master.c:2836
void ecrt_master_reset(ec_master_t *master)
Retry configuring slaves.
Definition: master.c:3281
void ecrt_master_sync_reference_clock(ec_master_t *master)
Queues the DC reference clock drift compensation datagram for sending.
Definition: master.c:2826
#define EC_READ_U8(DATA)
Read an 8-bit unsigned value from EtherCAT data.
Definition: ecrt.h:2162
#define EC_READ_U32(DATA)
Read a 32-bit unsigned value from EtherCAT data.
Definition: ecrt.h:2194
int ecrt_master_read_idn(ec_master_t *master, uint16_t slave_position, uint8_t drive_no, uint16_t idn, uint8_t *target, size_t target_size, size_t *result_size, uint16_t *error_code)
Executes an SoE read request.
Definition: master.c:3197
#define EC_WRITE_U16(DATA, VAL)
Write a 16-bit unsigned value to EtherCAT data.
Definition: ecrt.h:2283
#define EC_MAX_STRING_LENGTH
Maximum string length.
Definition: ecrt.h:219
void ecrt_master_sync_slave_clocks(ec_master_t *master)
Queues the DC clock drift compensation datagram for sending.
Definition: master.c:2849
void ecrt_sdo_request_index(ec_sdo_request_t *req, uint16_t index, uint8_t subindex)
Set the SDO index and subindex.
Definition: sdo_request.c:187
int ecrt_master_reference_clock_time(ec_master_t *master, uint32_t *time)
Get the lower 32 bit of the reference clock system time.
Definition: master.c:2807
int ecrt_master(ec_master_t *master, ec_master_info_t *master_info)
Obtains master information.
Definition: master.c:2667
void ecrt_sdo_request_write(ec_sdo_request_t *req)
Schedule an SDO write operation.
Definition: sdo_request.c:235
ec_domain_t * ecrt_master_create_domain_err(ec_master_t *master)
Same as ecrt_master_create_domain(), but with ERR_PTR() return value.
Definition: master.c:2274
void ec_master_request_op(ec_master_t *master)
Request OP state for configured slaves.
Definition: master.c:2240
void ec_master_leave_idle_phase(ec_master_t *master)
Transition function from IDLE to ORPHANED phase.
Definition: master.c:674
const unsigned int rate_intervals[]
List of intervals for statistics [s].
Definition: master.c:100
void ec_master_update_device_stats(ec_master_t *)
Updates the common device statistics.
Definition: master.c:1337
void ec_master_init_static(void)
Static variables initializer.
Definition: master.c:121
int ec_master_thread_start(ec_master_t *master, int(*thread_func)(void *), const char *name)
Starts the master thread.
Definition: master.c:580
static int ec_master_eoe_thread(void *)
Does the Ethernet over EtherCAT processing.
Definition: master.c:1743
int ec_master_calc_topology_rec(ec_master_t *master, ec_slave_t *port0_slave, unsigned int *slave_position)
Calculates the bus topology; recursion function.
Definition: master.c:2141
uint16_t ec_master_eoe_handler_count(const ec_master_t *master)
Get the number of EoE handlers.
Definition: master.c:2009
void ec_master_exec_slave_fsms(ec_master_t *master)
Execute slave FSMs.
Definition: master.c:1464
void ec_master_set_send_interval(ec_master_t *master, unsigned int send_interval)
Sets the expected interval between calls to ecrt_master_send and calculates the maximum amount of dat...
Definition: master.c:916
static int ec_master_idle_thread(void *)
Master kernel thread function for IDLE phase.
Definition: master.c:1554
static int ec_master_operation_thread(void *)
Master kernel thread function for OPERATION phase.
Definition: master.c:1625
int ec_master_init(ec_master_t *master, unsigned int index, const uint8_t *main_mac, const uint8_t *backup_mac, dev_t device_number, struct class *class, unsigned int debug_level, unsigned int run_on_cpu)
Master constructor.
Definition: master.c:142
ec_slave_config_t * ecrt_master_slave_config_err(ec_master_t *master, uint16_t alias, uint16_t position, uint32_t vendor_id, uint32_t product_code)
Same as ecrt_master_slave_config(), but with ERR_PTR() return value.
Definition: master.c:2578
void ec_master_calc_topology(ec_master_t *master)
Calculates the bus topology.
Definition: master.c:2184
int ec_master_enter_operation_phase(ec_master_t *master)
Transition function from IDLE to OPERATION phase.
Definition: master.c:698
void ec_master_find_dc_ref_clock(ec_master_t *)
Finds the DC reference clock.
Definition: master.c:2079
#define FORCE_OUTPUT_CORRUPTED
Always output corrupted frames.
Definition: master.c:71
void ec_master_queue_datagram_ext(ec_master_t *master, ec_datagram_t *datagram)
Places a datagram in the non-application datagram queue.
Definition: master.c:985
void ec_master_queue_datagram(ec_master_t *master, ec_datagram_t *datagram)
Places a datagram in the datagram queue.
Definition: master.c:952
void ec_master_eoe_start(ec_master_t *master)
Starts Ethernet over EtherCAT processing on demand.
Definition: master.c:1694
const ec_domain_t * ec_master_find_domain_const(const ec_master_t *master, unsigned int index)
Get a domain via its position in the list.
Definition: master.c:1992
const ec_eoe_t * ec_master_get_eoe_handler_const(const ec_master_t *master, uint16_t index)
Get an EoE handler via its position in the list.
Definition: master.c:2031
void ec_master_clear_domains(ec_master_t *)
Clear all domains.
Definition: master.c:520
void ec_master_clear_slave_configs(ec_master_t *)
Clear all slave configurations.
Definition: master.c:460
ec_domain_t * ec_master_find_domain(ec_master_t *master, unsigned int index)
Get a domain via its position in the list.
Definition: master.c:1977
void ec_master_receive_datagrams(ec_master_t *master, ec_device_t *device, const uint8_t *frame_data, size_t size)
Processes a received frame.
Definition: master.c:1137
void ec_master_inject_external_datagrams(ec_master_t *master)
Injects external datagrams that fit into the datagram queue.
Definition: master.c:802
int ec_master_enter_idle_phase(ec_master_t *master)
Transition function from ORPHANED to IDLE phase.
Definition: master.c:641
int ec_master_debug_level(ec_master_t *master, unsigned int level)
Set the debug level.
Definition: master.c:2056
ec_slave_t * ec_master_find_slave(ec_master_t *master, uint16_t alias, uint16_t position)
Finds a slave in the bus, given the alias and position.
Definition: master.c:1848
const ec_slave_config_t * ec_master_get_config_const(const ec_master_t *master, unsigned int pos)
Get a slave configuration via its position in the list.
Definition: master.c:1928
const ec_slave_t * ec_master_find_slave_const(const ec_master_t *master, uint16_t alias, uint16_t position)
Finds a slave in the bus, given the alias and position.
Definition: master.c:1864
void ec_master_calc_transmission_delays(ec_master_t *master)
Calculates the bus transmission delays.
Definition: master.c:2201
void ec_master_attach_slave_configs(ec_master_t *master)
Attaches the slave configurations to the slaves.
Definition: master.c:1808
void ec_master_calc_dc(ec_master_t *master)
Distributed-clocks calculations.
Definition: master.c:2223
void ec_master_clear_eoe_handlers(ec_master_t *master)
Clear and free all EoE handlers.
Definition: master.c:442
void ec_master_clear_slaves(ec_master_t *master)
Clear all slaves.
Definition: master.c:478
void ec_master_clear(ec_master_t *master)
Destructor.
Definition: master.c:395
unsigned int ec_master_config_count(const ec_master_t *master)
Get the number of slave configurations provided by the application.
Definition: master.c:1880
void ec_master_internal_send_cb(void *cb_data)
Internal sending callback.
Definition: master.c:549
void ec_master_send_datagrams(ec_master_t *master, ec_device_index_t device_index)
Sends the datagrams in the queue for a certain device.
Definition: master.c:1000
void ec_master_output_stats(ec_master_t *master)
Output master statistics.
Definition: master.c:1275
void ec_master_clear_config(ec_master_t *master)
Clear the configuration applied by the application.
Definition: master.c:535
void ec_master_eoe_stop(ec_master_t *master)
Stops the Ethernet over EtherCAT processing.
Definition: master.c:1728
#define EC_FIND_SLAVE
Common implementation for ec_master_find_slave() and ec_master_find_slave_const().
Definition: master.c:1824
void ec_master_clear_device_stats(ec_master_t *)
Clears the common device statistics.
Definition: master.c:1305
#define EC_FIND_DOMAIN
Common implementation for ec_master_find_domain() and ec_master_find_domain_const().
Definition: master.c:1962
ec_datagram_t * ec_master_get_external_datagram(ec_master_t *master)
Searches for a free datagram in the external datagram ring.
Definition: master.c:933
static unsigned long ext_injection_timeout_jiffies
Timeout for external datagram injection [jiffies].
Definition: master.c:94
#define EC_SDO_INJECTION_TIMEOUT
SDO injection timeout in microseconds.
Definition: master.c:74
#define EC_FIND_CONFIG
Common implementation for ec_master_get_config() and ec_master_get_config_const().
Definition: master.c:1899
void ec_master_leave_operation_phase(ec_master_t *master)
Transition function from OPERATION to IDLE phase.
Definition: master.c:780
unsigned int ec_master_domain_count(const ec_master_t *master)
Get the number of domains.
Definition: master.c:1943
ec_slave_config_t * ec_master_get_config(const ec_master_t *master, unsigned int pos)
Get a slave configuration via its position in the list.
Definition: master.c:1913
void ec_master_internal_receive_cb(void *cb_data)
Internal receiving callback.
Definition: master.c:563
void ec_master_thread_stop(ec_master_t *master)
Stops the master thread.
Definition: master.c:609
static unsigned long timeout_jiffies
Frame timeout in jiffies.
Definition: master.c:90
EtherCAT master structure.
#define ec_master_num_devices(MASTER)
Number of Ethernet devices.
Definition: master.h:330
#define EC_MASTER_INFO(master, fmt, args...)
Convenience macro for printing master-specific information to syslog.
Definition: master.h:73
#define EC_MASTER_DBG(master, level, fmt, args...)
Convenience macro for printing master-specific debug messages to syslog.
Definition: master.h:111
#define EC_EXT_RING_SIZE
Size of the external datagram ring.
Definition: master.h:124
@ EC_IDLE
Idle phase.
Definition: master.h:133
@ EC_ORPHANED
Orphaned phase.
Definition: master.h:131
@ EC_OPERATION
Operation phase.
Definition: master.h:135
#define EC_MASTER_ERR(master, fmt, args...)
Convenience macro for printing master-specific errors to syslog.
Definition: master.h:85
#define EC_MASTER_WARN(master, fmt, args...)
Convenience macro for printing master-specific warnings to syslog.
Definition: master.h:97
dev_t device_number
Device number for master cdevs.
Definition: module.c:67
static unsigned int run_on_cpu
Bind created kernel threads to a cpu.
Definition: module.c:62
static unsigned int debug_level
Debug level parameter.
Definition: module.c:61
void ec_rtdm_dev_clear(ec_rtdm_dev_t *rtdm_dev)
Clear an RTDM device.
Definition: rtdm.c:118
int ec_rtdm_dev_init(ec_rtdm_dev_t *rtdm_dev, ec_master_t *master)
Initialize an RTDM device.
Definition: rtdm.c:69
void ec_sdo_request_init(ec_sdo_request_t *req)
SDO request constructor.
Definition: sdo_request.c:56
int ec_sdo_request_alloc(ec_sdo_request_t *req, size_t size)
Pre-allocates the data memory.
Definition: sdo_request.c:127
void ec_sdo_request_clear(ec_sdo_request_t *req)
SDO request destructor.
Definition: sdo_request.c:76
void ec_slave_calc_port_delays(ec_slave_t *slave)
Calculates the port transmission delays.
Definition: slave.c:922
void ec_slave_request_state(ec_slave_t *slave, ec_slave_state_t state)
Request a slave state and resets the error flag.
Definition: slave.c:296
void ec_slave_clear(ec_slave_t *slave)
Slave destructor.
Definition: slave.c:170
void ec_slave_calc_transmission_delays_rec(ec_slave_t *slave, uint32_t *delay)
Recursively calculates transmission delays.
Definition: slave.c:968
uint16_t ec_slave_sdo_count(const ec_slave_t *slave)
Get the number of SDOs in the dictionary.
Definition: slave.c:706
EtherCAT slave structure.
#define EC_SLAVE_DBG(slave, level, fmt, args...)
Convenience macro for printing slave-specific debug messages to syslog.
Definition: slave.h:106
#define EC_SLAVE_ERR(slave, fmt, args...)
Convenience macro for printing slave-specific errors to syslog.
Definition: slave.h:76
void ec_slave_config_load_default_sync_config(ec_slave_config_t *sc)
Loads the default PDO assignment from the slave object.
Definition: slave_config.c:301
void ec_slave_config_clear(ec_slave_config_t *sc)
Slave configuration destructor.
Definition: slave_config.c:104
void ec_slave_config_init(ec_slave_config_t *sc, ec_master_t *master, uint16_t alias, uint16_t position, uint32_t vendor_id, uint32_t product_code)
Slave configuration constructor.
Definition: slave_config.c:56
int ec_slave_config_attach(ec_slave_config_t *sc)
Attaches the configuration to the addressed slave object.
Definition: slave_config.c:218
EtherCAT slave configuration structure.
void ec_soe_request_write(ec_soe_request_t *req)
Request a write operation.
Definition: soe_request.c:245
void ec_soe_request_set_idn(ec_soe_request_t *req, uint16_t idn)
Set IDN.
Definition: soe_request.c:117
void ec_soe_request_set_drive_no(ec_soe_request_t *req, uint8_t drive_no)
Set drive number.
Definition: soe_request.c:105
void ec_soe_request_read(ec_soe_request_t *req)
Request a read operation.
Definition: soe_request.c:232
void ec_soe_request_init(ec_soe_request_t *req)
SoE request constructor.
Definition: soe_request.c:56
int ec_soe_request_alloc(ec_soe_request_t *req, size_t size)
Pre-allocates the data memory.
Definition: soe_request.c:150
void ec_soe_request_clear(ec_soe_request_t *req)
SoE request destructor.
Definition: soe_request.c:77
EtherCAT datagram.
Definition: datagram.h:87
uint16_t working_counter
Working counter.
Definition: datagram.h:99
size_t data_size
Size of the data in data.
Definition: datagram.h:97
unsigned long jiffies_received
Jiffies, when the datagram was received.
Definition: datagram.h:108
ec_datagram_type_t type
Datagram type (APRD, BWR, etc.).
Definition: datagram.h:92
unsigned long jiffies_sent
Jiffies, when the datagram was sent.
Definition: datagram.h:104
struct list_head queue
Master datagram queue item.
Definition: datagram.h:88
uint8_t index
Index (set by master).
Definition: datagram.h:98
ec_datagram_state_t state
State.
Definition: datagram.h:100
ec_device_index_t device_index
Device via which the datagram shall be / was sent.
Definition: datagram.h:90
struct list_head sent
Master list item for sent datagrams.
Definition: datagram.h:89
uint8_t address[EC_ADDR_LEN]
Recipient address.
Definition: datagram.h:93
uint8_t * data
Datagram payload.
Definition: datagram.h:94
char name[EC_DATAGRAM_NAME_SIZE]
Description of the datagram.
Definition: datagram.h:112
unsigned int skip_count
Number of requeues when not yet received.
Definition: datagram.h:110
Device statistics.
Definition: master.h:155
s32 rx_byte_rates[EC_RATE_COUNT]
Receive rates in byte/s for different statistics cycle periods.
Definition: master.h:175
s32 loss_rates[EC_RATE_COUNT]
Frame loss rates for different statistics cycle periods.
Definition: master.h:177
u64 tx_count
Number of frames sent.
Definition: master.h:156
s32 rx_frame_rates[EC_RATE_COUNT]
Receive rates in frames/s for different statistics cycle periods.
Definition: master.h:170
u64 rx_bytes
Number of bytes received.
Definition: master.h:163
u64 last_loss
Tx/Rx difference of last statistics cycle.
Definition: master.h:166
u64 last_tx_bytes
Number of bytes sent of last statistics cycle.
Definition: master.h:162
u64 last_tx_count
Number of frames sent of last statistics cycle.
Definition: master.h:157
s32 tx_byte_rates[EC_RATE_COUNT]
Transmit rates in byte/s for different statistics cycle periods.
Definition: master.h:173
u64 tx_bytes
Number of bytes sent.
Definition: master.h:161
u64 rx_count
Number of frames received.
Definition: master.h:158
s32 tx_frame_rates[EC_RATE_COUNT]
Transmit rates in frames/s for different statistics cycle periods.
Definition: master.h:167
u64 last_rx_bytes
Number of bytes received of last statistics cycle.
Definition: master.h:164
u64 last_rx_count
Number of frames received of last statistics cycle.
Definition: master.h:159
unsigned long jiffies
Jiffies of last statistic cycle.
Definition: master.h:179
EtherCAT device.
Definition: device.h:82
struct sk_buff * tx_skb[EC_TX_RING_SIZE]
transmit skb ring
Definition: device.h:89
struct net_device * dev
pointer to the assigned net_device
Definition: device.h:84
uint8_t link_state
device link state
Definition: device.h:88
unsigned int tx_ring_index
last ring entry used to transmit
Definition: device.h:90
unsigned long jiffies_poll
jiffies of last poll
Definition: device.h:97
EtherCAT domain.
Definition: domain.h:55
struct list_head list
List item.
Definition: domain.h:56
size_t data_size
Size of the process data.
Definition: domain.h:61
unsigned int index
Index (just a number).
Definition: domain.h:58
Ethernet over EtherCAT (EoE) handler.
Definition: ethernet.h:77
unsigned int queue_datagram
the datagram is ready for queuing
Definition: ethernet.h:81
ec_slave_t * slave
pointer to the corresponding slave
Definition: ethernet.h:79
struct list_head list
list item
Definition: ethernet.h:78
unsigned int slaves_responding[EC_MAX_NUM_DEVICES]
Number of responding slaves for every device.
Definition: fsm_master.h:80
ec_sdo_request_t * sdo_request
SDO request to process.
Definition: fsm_master.h:90
ec_slave_state_t slave_states[EC_MAX_NUM_DEVICES]
AL states of responding slaves for every device.
Definition: fsm_master.h:84
Finite state machine of an EtherCAT slave.
Definition: fsm_slave.h:54
ec_datagram_t * datagram
Previous state datagram.
Definition: fsm_slave.h:59
ec_slave_t * slave
slave the FSM runs on
Definition: fsm_slave.h:55
struct list_head list
Used for execution list.
Definition: fsm_slave.h:56
Master information.
Definition: ecrt.h:341
unsigned int slave_count
Number of slaves in the bus.
Definition: ecrt.h:342
uint64_t app_time
Application time.
Definition: ecrt.h:345
uint8_t scan_busy
true, while the master is scanning the bus
Definition: ecrt.h:344
unsigned int link_up
true, if the network link is up.
Definition: ecrt.h:343
Master state.
Definition: ecrt.h:271
unsigned int al_states
Application-layer states of all slaves.
Definition: ecrt.h:274
unsigned int slaves_responding
Sum of responding slaves on all Ethernet devices.
Definition: ecrt.h:272
unsigned int link_up
true, if at least one Ethernet link is up.
Definition: ecrt.h:283
EtherCAT master.
Definition: master.h:194
struct list_head datagram_queue
Datagram queue.
Definition: master.h:263
struct task_struct * eoe_thread
EoE thread.
Definition: master.h:292
unsigned int injection_seq_fsm
Datagram injection sequence number for the FSM side.
Definition: master.h:226
struct task_struct * thread
Master thread.
Definition: master.h:289
struct list_head eoe_handlers
Ethernet over EtherCAT handlers.
Definition: master.h:293
ec_datagram_t fsm_datagram
Datagram used for state machines.
Definition: master.h:222
struct list_head emerg_reg_requests
Emergency register access requests.
Definition: master.h:308
struct semaphore master_sem
Master semaphore.
Definition: master.h:209
struct list_head ext_datagram_queue
Queue for non-application datagrams.
Definition: master.h:266
ec_datagram_t sync_datagram
Datagram used for DC drift compensation.
Definition: master.h:242
size_t max_queue_size
Maximum size of datagram queue.
Definition: master.h:279
wait_queue_head_t request_queue
Wait queue for external requests from user space.
Definition: master.h:311
struct list_head fsm_exec_list
Slave FSM execution list.
Definition: master.h:282
struct list_head sii_requests
SII write requests.
Definition: master.h:307
ec_fsm_master_t fsm
Master state machine.
Definition: master.h:221
u64 app_time
Time of the last ecrt_master_sync() call.
Definition: master.h:238
wait_queue_head_t scan_queue
Queue for processes that wait for slave scanning.
Definition: master.h:254
struct semaphore io_sem
Semaphore used in IDLE phase.
Definition: master.h:296
unsigned int scan_busy
Current scan state.
Definition: master.h:250
unsigned int send_interval
Interval between two calls to ecrt_master_send().
Definition: master.h:277
unsigned int slave_count
Number of slaves on the bus.
Definition: master.h:232
void * app_cb_data
Application callback data.
Definition: master.h:305
void(* app_receive_cb)(void *)
Application's receive datagrams callback.
Definition: master.h:303
void(* receive_cb)(void *)
Current receive datagrams callback.
Definition: master.h:299
uint8_t datagram_index
Current datagram index.
Definition: master.h:264
unsigned int index
Index.
Definition: master.h:195
unsigned int ext_ring_idx_fsm
Index in external datagram ring for FSM side.
Definition: master.h:275
ec_device_stats_t device_stats
Device statistics.
Definition: master.h:219
void(* send_cb)(void *)
Current send datagrams callback.
Definition: master.h:298
unsigned int config_busy
State of slave configuration.
Definition: master.h:257
ec_slave_t * dc_ref_clock
DC reference clock slave.
Definition: master.h:248
ec_datagram_t ref_sync_datagram
Datagram used for synchronizing the reference clock to the master clock.
Definition: master.h:240
struct list_head domains
List of domains.
Definition: master.h:236
struct semaphore config_sem
Semaphore protecting the config_busy variable and the allow_config flag.
Definition: master.h:258
unsigned int fsm_exec_count
Number of entries in execution list.
Definition: master.h:283
void(* app_send_cb)(void *)
Application's send datagrams callback.
Definition: master.h:301
u64 dc_ref_time
Common reference timestamp for DC start times.
Definition: master.h:239
ec_slave_t * fsm_slave
Slave that is queried next for FSM exec.
Definition: master.h:281
unsigned int injection_seq_rt
Datagram injection sequence number for the realtime side.
Definition: master.h:228
wait_queue_head_t config_queue
Queue for processes that wait for slave configuration.
Definition: master.h:260
struct semaphore scan_sem
Semaphore protecting the scan_busy variable and the allow_scan flag.
Definition: master.h:252
unsigned int run_on_cpu
bind kernel threads to this cpu
Definition: master.h:286
ec_datagram_t sync_mon_datagram
Datagram used for DC synchronisation monitoring.
Definition: master.h:244
ec_slave_t * slaves
Array of slaves on the bus.
Definition: master.h:231
unsigned int active
Master has been activated.
Definition: master.h:224
unsigned int ext_ring_idx_rt
Index in external datagram ring for RT side.
Definition: master.h:273
unsigned int debug_level
Master debug level.
Definition: master.h:285
ec_stats_t stats
Cyclic statistics.
Definition: master.h:287
ec_slave_config_t * dc_ref_config
Application-selected DC reference clock slave config.
Definition: master.h:246
struct device * class_device
Master class device.
Definition: master.h:200
struct semaphore device_sem
Device semaphore.
Definition: master.h:218
ec_cdev_t cdev
Master character device.
Definition: master.h:198
unsigned int reserved
True, if the master is in use.
Definition: master.h:196
unsigned int allow_scan
True, if slave scanning is allowed.
Definition: master.h:251
unsigned int config_changed
The configuration changed.
Definition: master.h:225
struct list_head configs
List of slave configurations.
Definition: master.h:235
const uint8_t * macs[EC_MAX_NUM_DEVICES]
Device MAC addresses.
Definition: master.h:212
ec_datagram_t ext_datagram_ring[EC_EXT_RING_SIZE]
External datagram ring.
Definition: master.h:271
ec_master_phase_t phase
Master phase.
Definition: master.h:223
ec_device_t devices[EC_MAX_NUM_DEVICES]
EtherCAT devices.
Definition: master.h:211
void * cb_data
Current callback data.
Definition: master.h:300
struct semaphore ext_queue_sem
Semaphore protecting the ext_datagram_queue.
Definition: master.h:268
CANopen SDO request.
Definition: sdo_request.h:48
ec_internal_request_state_t state
SDO request state.
Definition: sdo_request.h:63
int errno
Error number.
Definition: sdo_request.h:67
struct list_head list
List item.
Definition: sdo_request.h:49
uint8_t complete_access
SDO shall be transferred completely.
Definition: sdo_request.h:55
size_t data_size
Size of SDO data.
Definition: sdo_request.h:54
uint8_t * data
Pointer to SDO data.
Definition: sdo_request.h:52
uint32_t abort_code
SDO request abort code.
Definition: sdo_request.h:68
uint32_t serial_number
Serial number.
Definition: slave.h:138
int16_t current_on_ebus
Power consumption in mA.
Definition: slave.h:162
uint32_t product_code
Vendor-specific product code.
Definition: slave.h:136
uint32_t revision_number
Revision number.
Definition: slave.h:137
uint32_t vendor_id
Vendor ID.
Definition: slave.h:135
unsigned int sync_count
Number of sync managers.
Definition: slave.h:166
char * name
Slave name.
Definition: slave.h:158
SII write request.
Definition: fsm_master.h:53
struct list_head list
List head.
Definition: fsm_master.h:54
ec_slave_t * slave
EtherCAT slave.
Definition: fsm_master.h:55
ec_internal_request_state_t state
State of the request.
Definition: fsm_master.h:59
EtherCAT slave configuration.
Definition: slave_config.h:119
uint32_t product_code
Slave product code.
Definition: slave_config.h:127
struct list_head list
List item.
Definition: slave_config.h:120
uint16_t alias
Slave alias.
Definition: slave_config.h:123
ec_slave_t * slave
Slave pointer.
Definition: slave_config.h:134
uint32_t vendor_id
Slave vendor ID.
Definition: slave_config.h:126
uint16_t position
Index after alias.
Definition: slave_config.h:124
Slave information.
Definition: ecrt.h:377
uint32_t delay_to_next_dc
Delay [ns] to next DC slave.
Definition: ecrt.h:392
uint32_t revision_number
Revision-Number stored on the slave.
Definition: ecrt.h:381
uint8_t error_flag
Error flag for that slave.
Definition: ecrt.h:395
int16_t current_on_ebus
Used current in mA.
Definition: ecrt.h:384
uint16_t position
Offset of the slave in the ring.
Definition: ecrt.h:378
uint16_t next_slave
Ring position of next DC slave on that port.
Definition: ecrt.h:390
uint8_t al_state
Current state of the slave.
Definition: ecrt.h:394
uint32_t product_code
Product-Code stored on the slave.
Definition: ecrt.h:380
ec_slave_port_link_t link
Port link state.
Definition: ecrt.h:387
uint32_t vendor_id
Vendor-ID stored on the slave.
Definition: ecrt.h:379
uint16_t alias
The slaves alias if not equal to 0.
Definition: ecrt.h:383
uint32_t serial_number
Serial-Number stored on the slave.
Definition: ecrt.h:382
ec_slave_port_desc_t desc
Physical port type.
Definition: ecrt.h:386
char name[EC_MAX_STRING_LENGTH]
Name of the slave.
Definition: ecrt.h:398
uint16_t sdo_count
Number of SDOs.
Definition: ecrt.h:397
uint8_t sync_count
Number of sync managers.
Definition: ecrt.h:396
uint32_t receive_time
Receive time on DC transmission delay measurement.
Definition: ecrt.h:388
struct ec_slave_info_t::@3 ports[EC_MAX_PORTS]
Port information.
uint32_t receive_time
Port receive times for delay measurement.
Definition: slave.h:122
ec_slave_t * next_slave
Connected slaves.
Definition: slave.h:121
ec_slave_port_link_t link
Port link status.
Definition: slave.h:120
uint32_t delay_to_next_dc
Delay to next slave with DC support behind this port [ns].
Definition: slave.h:124
ec_slave_port_desc_t desc
Port descriptors.
Definition: slave.h:119
EtherCAT slave.
Definition: slave.h:177
ec_sii_t sii
Extracted SII data.
Definition: slave.h:223
unsigned int force_config
Force (re-)configuration.
Definition: slave.h:194
ec_slave_port_t ports[EC_MAX_PORTS]
Ports.
Definition: slave.h:187
uint32_t transmission_delay
DC system time transmission delay (offset from reference clock).
Definition: slave.h:215
uint8_t base_dc_supported
Distributed clocks are supported.
Definition: slave.h:210
uint16_t ring_position
Ring position.
Definition: slave.h:183
ec_slave_config_t * config
Current configuration.
Definition: slave.h:190
ec_slave_state_t current_state
Current application state.
Definition: slave.h:192
uint8_t has_dc_system_time
The slave supports the DC system time register.
Definition: slave.h:212
struct list_head sdo_requests
SDO access requests.
Definition: slave.h:229
struct list_head soe_requests
SoE write requests.
Definition: slave.h:232
uint16_t effective_alias
Effective alias address.
Definition: slave.h:185
uint16_t station_address
Configured station address.
Definition: slave.h:184
ec_fsm_slave_t fsm
Slave state machine.
Definition: slave.h:234
unsigned int error_flag
Stop processing after an error.
Definition: slave.h:193
Sercos-over-EtherCAT request.
Definition: soe_request.h:48
struct list_head list
List item.
Definition: soe_request.h:49
uint8_t * data
Pointer to SDO data.
Definition: soe_request.h:53
uint16_t error_code
SoE error code.
Definition: soe_request.h:61
ec_internal_request_state_t state
Request state.
Definition: soe_request.h:58
size_t data_size
Size of SDO data.
Definition: soe_request.h:55
unsigned int corrupted
corrupted frames
Definition: master.h:145
unsigned long output_jiffies
time of last output
Definition: master.h:148
unsigned int timeouts
datagram timeouts
Definition: master.h:144
unsigned int unmatched
unmatched datagrams (received, but not queued any longer)
Definition: master.h:146