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