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