39 #include <linux/module.h> 40 #include <linux/kernel.h> 41 #include <linux/string.h> 42 #include <linux/slab.h> 43 #include <linux/delay.h> 44 #include <linux/device.h> 45 #include <linux/version.h> 46 #include <linux/hrtimer.h> 47 #include <linux/vmalloc.h> 49 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) 50 #include <linux/sched/types.h> 51 #include <linux/sched/signal.h> 64 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,11,0) 65 #include <linux/sched/signal.h> 66 #include <uapi/linux/sched/types.h> 73 #define DEBUG_INJECT 0 77 #define FORCE_OUTPUT_CORRUPTED 0 83 static cycles_t timeout_cycles;
87 static cycles_t ext_injection_timeout_cycles;
126 #ifdef EC_HAVE_CYCLES 127 timeout_cycles = (cycles_t)
EC_IO_TIMEOUT * (cpu_khz / 1000);
128 ext_injection_timeout_cycles =
147 const uint8_t *main_mac,
148 const uint8_t *backup_mac,
155 unsigned int dev_idx, i;
157 master->
index = index;
162 for (dev_idx =
EC_DEVICE_MAIN; dev_idx < EC_MAX_NUM_DEVICES; dev_idx++) {
163 master->
macs[dev_idx] = NULL;
168 #if EC_MAX_NUM_DEVICES > 1 191 INIT_LIST_HEAD(&master->
configs);
192 INIT_LIST_HEAD(&master->
domains);
254 ec_lock_init(&master->
io_sem);
272 goto out_clear_devices;
283 goto out_clear_devices;
295 " datagram %u.\n", i);
296 goto out_clear_ext_datagrams;
308 " synchronisation datagram.\n");
309 goto out_clear_ext_datagrams;
319 " synchronisation datagram.\n");
320 goto out_clear_ref_sync;
330 " system clock datagram.\n");
342 " monitoring datagram.\n");
343 goto out_clear_sync64;
352 goto out_clear_sync_mon;
354 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) 356 MKDEV(MAJOR(device_number), master->
index), NULL,
357 "EtherCAT%u", master->
index);
358 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) 360 MKDEV(MAJOR(device_number), master->
index),
361 "EtherCAT%u", master->
index);
362 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 15) 364 MKDEV(MAJOR(device_number), master->
index), NULL,
365 "EtherCAT%u", master->
index);
368 MKDEV(MAJOR(device_number), master->
index), NULL,
369 "EtherCAT%u", master->
index);
381 goto out_unregister_class_device;
388 out_unregister_class_device:
389 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) 405 out_clear_ext_datagrams:
412 for (; dev_idx > 0; dev_idx--) {
426 unsigned int dev_idx, i;
432 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) 482 unsigned int free_all
487 list_for_each_entry_safe(eoe, next, &master->
eoe_handlers, list) {
490 list_del(&eoe->
list);
511 list_for_each_entry_safe(sc, next, &master->
configs, list) {
544 list_for_each_entry_safe(pdo, next_pdo, &sii_image->
sii.
pdos, list) {
545 list_del(&pdo->
list);
550 if (sii_image->words) {
551 kfree(sii_image->words);
565 list_for_each_entry_safe(sii_image, next, &master->
sii_images, list) {
571 list_del(&sii_image->
list);
619 list_del_init(&request->
list);
620 EC_MASTER_WARN(master,
"Discarding SII request, slave %s-%u about" 623 request->
state = EC_INT_REQUEST_FAILURE;
631 for (slave = master->
slaves;
653 list_for_each_entry_safe(domain, next, &master->
domains, list) {
654 list_del(&domain->
list);
683 ec_lock_down(&master->
io_sem);
685 ec_lock_up(&master->
io_sem);
697 ec_lock_down(&master->
io_sem);
699 ec_lock_up(&master->
io_sem);
711 int (*thread_func)(
void *),
716 master->
thread = kthread_run(thread_func, master, name);
717 if (IS_ERR(master->
thread)) {
718 int err = (int) PTR_ERR(master->
thread);
719 EC_MASTER_ERR(master,
"Failed to start master thread (error %i)!\n",
736 unsigned long sleep_jiffies;
745 kthread_stop(master->
thread);
754 sleep_jiffies = max(HZ / 100, 1);
755 schedule_timeout(sleep_jiffies);
772 int master_index = 0;
773 uint16_t alias, ring_position = 0;
798 if ((ret == 0) && (master_index == master->
index)) {
800 "alias %u, ring position %u.\n",
802 ecrt_master_eoe_addif(master, alias, ring_position);
863 " interrupted by signal.\n");
868 " configuration returned.\n");
881 ret = wait_event_interruptible(master->
scan_queue,
885 " interrupted by signal.\n");
890 " slave scan returned.\n");
894 for (slave = master->
slaves;
943 size_t queue_size = 0, new_queue_size = 0;
945 unsigned int datagram_count = 0;
960 EC_MASTER_DBG(master, 1,
"Injecting datagrams, queue_size=%zu\n",
974 new_queue_size = queue_size + datagram->
data_size;
975 if (new_queue_size <= master->max_queue_size) {
978 " size=%zu, queue_size=%zu\n", datagram->
name,
982 #ifdef EC_HAVE_CYCLES 983 datagram->cycles_sent = 0;
987 queue_size = new_queue_size;
992 " size=%zu, max_queue_size=%zu\n",
997 #ifdef EC_HAVE_CYCLES 998 cycles_t cycles_now = get_cycles();
1000 if (cycles_now - datagram->cycles_sent
1001 > ext_injection_timeout_cycles)
1007 #if defined EC_RT_SYSLOG || DEBUG_INJECT 1008 unsigned int time_us;
1013 #if defined EC_RT_SYSLOG || DEBUG_INJECT 1014 #ifdef EC_HAVE_CYCLES 1015 time_us = (
unsigned int)
1016 ((cycles_now - datagram->cycles_sent) * 1000LL)
1019 time_us = (
unsigned int)
1023 " external datagram %s size=%zu," 1024 " max_queue_size=%zu\n", time_us, datagram->
name,
1031 " external datagram %s size=%u, queue_size=%u\n",
1043 EC_MASTER_DBG(master, 1,
"Injected %u datagrams.\n", datagram_count);
1054 unsigned int send_interval
1089 #ifdef EC_HAVE_CYCLES 1090 datagram->cycles_sent = get_cycles();
1118 list_for_each_entry(queued_datagram, &master->
datagram_queue, queue) {
1119 if (queued_datagram == datagram) {
1123 "Datagram %p already queued (skipping).\n", datagram);
1152 static int index_in_use(
ec_master_t *master, uint8_t index)
1170 size_t datagram_size;
1171 uint8_t *frame_data, *cur_data = NULL;
1173 #ifdef EC_HAVE_CYCLES 1174 cycles_t cycles_start, cycles_sent, cycles_end;
1176 unsigned long jiffies_sent;
1177 unsigned int frame_count, more_datagrams_waiting;
1178 struct list_head sent_datagrams;
1179 size_t sent_bytes = 0;
1182 #ifdef EC_HAVE_CYCLES 1183 cycles_start = get_cycles();
1186 INIT_LIST_HEAD(&sent_datagrams);
1189 __func__, device_index);
1193 follows_word = NULL;
1194 more_datagrams_waiting = 0;
1213 if (cur_data - frame_data + datagram_size > ETH_DATA_LEN) {
1214 more_datagrams_waiting = 1;
1223 EC_MASTER_ERR(master,
"No free datagram index, sending delayed\n");
1229 list_add_tail(&datagram->
sent, &sent_datagrams);
1246 follows_word = cur_data + 6;
1259 if (list_empty(&sent_datagrams)) {
1269 while (cur_data - frame_data < ETH_ZLEN - ETH_HLEN)
1272 EC_MASTER_DBG(master, 2,
"frame size: %zu\n", cur_data - frame_data);
1276 cur_data - frame_data);
1278 sent_bytes += ETH_HLEN + cur_data - frame_data + ETH_FCS_LEN + 20;
1279 #ifdef EC_HAVE_CYCLES 1280 cycles_sent = get_cycles();
1282 jiffies_sent = jiffies;
1285 list_for_each_entry_safe(datagram, next, &sent_datagrams, sent) {
1287 #ifdef EC_HAVE_CYCLES 1288 datagram->cycles_sent = cycles_sent;
1292 list_del_init(&datagram->
sent);
1299 #ifdef EC_HAVE_CYCLES 1301 cycles_end = get_cycles();
1303 " sent %u frames in %uus.\n", __func__, frame_count,
1304 (
unsigned int) (cycles_end - cycles_start) * 1000 / cpu_khz);
1321 const uint8_t *frame_data,
1325 size_t frame_size, data_size;
1326 uint8_t datagram_type, datagram_index, datagram_mbox_prot;
1330 unsigned int cmd_follows, datagram_slave_addr, datagram_offset_addr, datagram_wc, matched;
1331 const uint8_t *cur_data;
1338 " on %s (size %zu < %u byte):\n",
1349 cur_data = frame_data;
1355 if (unlikely(frame_size > size)) {
1358 " on %s (invalid frame size %zu for " 1359 "received size %zu):\n", device->
dev->name,
1371 while (cmd_follows) {
1381 if (unlikely(cur_data - frame_data
1385 " on %s (invalid data size %zu):\n",
1386 device->
dev->name, data_size);
1399 if (datagram->
index == datagram_index
1401 && datagram->
type == datagram_type
1420 #ifdef EC_DEBUG_RING 1438 if (master->
slaves != NULL) {
1439 for (slave = master->
slaves; slave < master->slaves + master->
slave_count; slave++) {
1459 if ((slave->
mbox_mbg_data.
data) && (data_size <= slave->mbox_mbg_data.data_size)) {
1464 datagram_mbox_prot =
EC_READ_U8(cur_data + 5) & 0x0F;
1465 switch (datagram_mbox_prot) {
1467 case EC_MBOX_TYPE_EOE:
1473 case EC_EOE_TYPE_FRAME_FRAG:
1488 EC_MASTER_DBG(master, 1,
"Unhandled EoE protocol type from slave: %u Protocol: %u, Type: %x\n",
1489 datagram_slave_addr, datagram_mbox_prot, eoe_type);
1491 memcpy(datagram->
data, cur_data, data_size);
1496 case EC_MBOX_TYPE_COE:
1497 if ((slave->
mbox_coe_data.
data) && (data_size <= slave->mbox_coe_data.data_size)) {
1502 case EC_MBOX_TYPE_FOE:
1503 if ((slave->
mbox_foe_data.
data) && (data_size <= slave->mbox_foe_data.data_size)) {
1508 case EC_MBOX_TYPE_SOE:
1509 if ((slave->
mbox_soe_data.
data) && (data_size <= slave->mbox_soe_data.data_size)) {
1514 case EC_MBOX_TYPE_VOE:
1515 if ((slave->
mbox_voe_data.
data) && (data_size <= slave->mbox_voe_data.data_size)) {
1521 EC_MASTER_DBG(master, 1,
"Unknown mailbox protocol from slave: %u Protocol: %u\n", datagram_slave_addr, datagram_mbox_prot);
1523 memcpy(datagram->
data, cur_data, data_size);
1529 memcpy(datagram->
data, cur_data, data_size);
1533 memcpy(datagram->
data, cur_data, data_size);
1537 memcpy(datagram->
data, cur_data, data_size);
1540 EC_MASTER_DBG(master, 1,
"No slave matching datagram slave address: %u\n", datagram_slave_addr);
1545 memcpy(datagram->
data, cur_data, data_size);
1549 memcpy(datagram->
data, cur_data, data_size);
1553 memcpy(datagram->
data, cur_data, data_size);
1556 cur_data += data_size;
1562 #ifdef EC_HAVE_CYCLES 1563 datagram->cycles_received =
1573 list_del_init(&datagram->
queue);
1652 s32 tx_frame_rate, rx_frame_rate, tx_byte_rate, rx_byte_rate, loss_rate;
1654 unsigned int i, dev_idx;
1657 if (likely(jiffies - s->
jiffies < HZ)) {
1666 loss_rate = (loss - s->
last_loss) * 1000;
1697 #ifdef EC_USE_HRTIMER 1702 static enum hrtimer_restart ec_master_nanosleep_wakeup(
struct hrtimer *timer)
1704 struct hrtimer_sleeper *t =
1705 container_of(timer,
struct hrtimer_sleeper, timer);
1706 struct task_struct *task = t->task;
1710 wake_up_process(task);
1712 return HRTIMER_NORESTART;
1717 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) 1720 static inline ktime_t hrtimer_get_expires(
const struct hrtimer *timer)
1722 return timer->expires;
1727 static inline void hrtimer_set_expires(
struct hrtimer *timer, ktime_t time)
1729 timer->expires = time;
1736 void ec_master_nanosleep(
const unsigned long nsecs)
1738 struct hrtimer_sleeper t;
1739 enum hrtimer_mode mode = HRTIMER_MODE_REL;
1741 hrtimer_init(&t.timer, CLOCK_MONOTONIC, mode);
1742 t.timer.function = ec_master_nanosleep_wakeup;
1744 #ifdef CONFIG_HIGH_RES_TIMERS 1745 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 24) 1746 t.timer.cb_mode = HRTIMER_CB_IRQSAFE_NO_RESTART;
1747 #elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 26) 1748 t.timer.cb_mode = HRTIMER_CB_IRQSAFE_NO_SOFTIRQ;
1749 #elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 28) 1750 t.timer.cb_mode = HRTIMER_CB_IRQSAFE_UNLOCKED;
1753 hrtimer_set_expires(&t.timer, ktime_set(0, nsecs));
1756 set_current_state(TASK_INTERRUPTIBLE);
1757 hrtimer_start(&t.timer, hrtimer_get_expires(&t.timer), mode);
1762 hrtimer_cancel(&t.timer);
1763 mode = HRTIMER_MODE_ABS;
1765 }
while (t.task && !signal_pending(current));
1768 #endif // EC_USE_HRTIMER 1780 unsigned int count = 0;
1782 list_for_each_entry_safe(fsm, next, &master->
fsm_exec_list, list) {
1787 list_del_init(&fsm->
list);
1804 " slave FSM execution. This is a bug!\n");
1826 list_del_init(&fsm->
list);
1836 && count < master->slave_count) {
1851 " consumed datagram %s, now %u FSMs in list.\n",
1880 EC_MASTER_DBG(master, 1,
"Idle thread running with send interval = %u us," 1884 while (!kthread_should_stop()) {
1888 ec_lock_down(&master->
io_sem);
1890 ec_lock_up(&master->
io_sem);
1893 if (ec_lock_down_interruptible(&master->
master_sem)) {
1905 ec_lock_down(&master->
io_sem);
1910 ec_lock_up(&master->
io_sem);
1913 #ifdef EC_USE_HRTIMER 1916 set_current_state(TASK_INTERRUPTIBLE);
1917 schedule_timeout(1);
1920 #ifdef EC_USE_HRTIMER 1921 ec_master_nanosleep(
1929 EC_MASTER_DBG(master, 1,
"Master IDLE thread exiting...\n");
1943 " with fsm interval = %u us, max data size=%zu\n",
1946 while (!kthread_should_stop()) {
1954 if (ec_lock_down_interruptible(&master->
master_sem)) {
1974 #ifdef EC_USE_HRTIMER 1979 set_current_state(TASK_INTERRUPTIBLE);
1980 schedule_timeout(1);
1999 struct sched_param param = { .sched_priority = 0 };
2022 EC_MASTER_ERR(master,
"Failed to start EoE thread (error %i)!\n",
2028 sched_setscheduler(master->
eoe_thread, SCHED_NORMAL, ¶m);
2065 return -ENOPROTOOPT;
2069 list_for_each_entry(eoe, &master->
eoe_handlers, list) {
2090 int sth_to_send = 0;
2091 int sth_pending = 0;
2100 list_for_each_entry(eoe, &master->
eoe_handlers, list) {
2116 list_for_each_entry(eoe, &master->
eoe_handlers, list) {
2122 return sth_to_send + sth_pending;
2135 unsigned int none_open, sth_to_send, all_idle;
2139 while (!kthread_should_stop()) {
2144 list_for_each_entry(eoe, &master->
eoe_handlers, list) {
2162 list_for_each_entry(eoe, &master->
eoe_handlers, list) {
2180 list_for_each_entry(eoe, &master->
eoe_handlers, list) {
2191 set_current_state(TASK_INTERRUPTIBLE);
2192 schedule_timeout(1);
2213 list_for_each_entry(sc, &master->
configs, list) {
2228 list_for_each_entry(sc, &master->
configs, list) {
2238 #define EC_FIND_SLAVE \ 2241 for (; slave < master->slaves + master->slave_count; \ 2243 if (slave->effective_alias == alias) \ 2246 if (slave == master->slaves + master->slave_count) \ 2250 slave += position; \ 2251 if (slave < master->slaves + master->slave_count) { \ 2299 unsigned int count = 0;
2301 list_for_each_entry(sc, &master->
configs, list) {
2313 #define EC_FIND_CONFIG \ 2315 list_for_each_entry(sc, &master->configs, list) { \ 2362 unsigned int count = 0;
2364 list_for_each_entry(domain, &master->
domains, list) {
2376 #define EC_FIND_DOMAIN \ 2378 list_for_each_entry(domain, &master->domains, list) { \ 2428 unsigned int count = 0;
2430 list_for_each_entry(eoe, &master->
eoe_handlers, list) {
2452 list_for_each_entry(eoe, &master->
eoe_handlers, list) {
2506 EC_MASTER_INFO(master,
"Using slave %s-%u as application selected" 2511 EC_MASTER_WARN(master,
"Application selected slave %s-%u can not" 2518 " config (%u-%u) has no slave attached!\n",
2526 for (slave = master->
slaves;
2540 EC_MASTER_INFO(master,
"Using slave %s-%u as DC reference clock.\n",
2566 unsigned int *slave_position
2570 unsigned int port_index;
2582 *slave_position = *slave_position + 1;
2583 if (*slave_position < master->slave_count) {
2585 master->
slaves + *slave_position;
2587 slave, slave_position);
2596 port_index = next_table[port_index];
2610 unsigned int slave_position = 0;
2616 for (slave = master->
slaves;
2623 EC_MASTER_ERR(master,
"Failed to calculate bus topology.\n");
2636 for (slave = master->
slaves;
2683 slave = master->
slaves + i;
2699 int ec_master_dict_upload(
ec_master_t *master, uint16_t slave_position)
2705 EC_MASTER_DBG(master, 1,
"%s(master = 0x%p, slave_position = %u\n",
2706 __func__, master, slave_position);
2709 ec_dict_request_read(&request);
2711 if (ec_lock_down_interruptible(&master->
master_sem)) {
2717 EC_MASTER_ERR(master,
"Slave %u does not exist!\n", slave_position);
2721 EC_SLAVE_DBG(slave, 1,
"Scheduling dictionary upload request.\n");
2730 request.
state != EC_INT_REQUEST_QUEUED)) {
2733 if (request.
state == EC_INT_REQUEST_QUEUED) {
2734 list_del(&request.
list);
2745 if (request.
state != EC_INT_REQUEST_SUCCESS) {
2766 EC_MASTER_DBG(master, 1,
"ecrt_master_create_domain(master = 0x%p)\n",
2772 return ERR_PTR(-ENOMEM);
2777 if (list_empty(&master->
domains)) {
2781 index = last_domain->
index + 1;
2801 return IS_ERR(d) ? NULL : d;
2816 uint32_t domain_offset;
2820 int eoe_was_running;
2823 EC_MASTER_DBG(master, 1,
"ecrt_master_activate(master = 0x%p)\n", master);
2826 EC_MASTER_WARN(master,
"%s: Master already active!\n", __func__);
2834 list_for_each_entry(domain, &master->
domains, list) {
2838 EC_MASTER_ERR(master,
"Failed to finish domain 0x%p!\n", domain);
2850 eoe_was_running = (master->
eoe_thread != NULL);
2864 if (eoe_was_running) {
2894 EC_MASTER_DBG(master, 1,
"%s(master = 0x%p)\n", __func__, master);
2903 list_for_each_entry_safe(sc, next, &master->
configs, list) {
2910 for (slave = master->
slaves;
2930 EC_MASTER_DBG(master, 1,
"%s(master = 0x%p)\n", __func__, master);
2949 for (slave = master->
slaves;
2990 size_t sent_bytes = 0;
3005 list_for_each_entry_safe(datagram, n,
3009 list_del_init(&datagram->
queue);
3026 sent_bytes = max(sent_bytes,
3037 unsigned int dev_idx;
3048 list_for_each_entry_safe(datagram, next, &master->
datagram_queue, queue) {
3051 #ifdef EC_HAVE_CYCLES 3053 datagram->cycles_sent > timeout_cycles) {
3058 list_del_init(&datagram->
queue);
3066 unsigned int time_us;
3067 #ifdef EC_HAVE_CYCLES 3068 time_us = (
unsigned int)
3070 datagram->cycles_sent) * 1000 / cpu_khz;
3072 time_us = (
unsigned int)
3077 " index %02X waited %u us.\n",
3078 datagram, datagram->
index, time_us);
3095 list_del(&datagram->
queue);
3108 uint16_t alias, uint16_t position, uint32_t vendor_id,
3109 uint32_t product_code)
3112 unsigned int found = 0;
3115 EC_MASTER_DBG(master, 1,
"ecrt_master_slave_config(master = 0x%p," 3116 " alias = %u, position = %u, vendor_id = 0x%08x," 3117 " product_code = 0x%08x)\n",
3118 master, alias, position, vendor_id, product_code);
3120 list_for_each_entry(sc, &master->
configs, list) {
3130 " configured as 0x%08X/0x%08X before. Now configuring" 3132 vendor_id, product_code);
3133 return ERR_PTR(-ENOENT);
3136 EC_MASTER_DBG(master, 1,
"Creating slave configuration for %u:%u," 3137 " 0x%08X/0x%08X.\n",
3138 alias, position, vendor_id, product_code);
3143 " for slave configuration.\n");
3144 return ERR_PTR(-ENOMEM);
3148 alias, position, vendor_id, product_code);
3166 uint16_t alias, uint16_t position, uint32_t vendor_id,
3167 uint32_t product_code)
3170 position, vendor_id, product_code);
3171 return IS_ERR(sc) ? NULL : sc;
3183 " config (%u-%u) set by application.\n",
3189 " config cleared by application.\n");
3203 " master_info = 0x%p)\n", master, master_info);
3221 if (ec_lock_down_interruptible(&master->
master_sem)) {
3227 if (slave == NULL) {
3233 EC_MASTER_WARN(master,
"Cannot access SII data from slave position %s-%u",
3275 slave_info->
name[0] = 0;
3287 void (*send_cb)(
void *),
void (*receive_cb)(
void *),
void *cb_data)
3289 EC_MASTER_DBG(master, 1,
"ecrt_master_callbacks(master = 0x%p," 3290 " send_cb = 0x%p, receive_cb = 0x%p, cb_data = 0x%p)\n",
3291 master, send_cb, receive_cb, cb_data);
3460 uint16_t index, uint8_t subindex,
const uint8_t *data,
3461 size_t data_size, uint32_t *abort_code)
3468 " slave_position = %u, index = 0x%04X, subindex = 0x%02X," 3469 " data = 0x%p, data_size = %zu, abort_code = 0x%p)\n",
3470 __func__, master, slave_position, index, subindex,
3471 data, data_size, abort_code);
3486 memcpy(request.
data, data, data_size);
3490 if (ec_lock_down_interruptible(&master->
master_sem)) {
3497 EC_MASTER_ERR(master,
"Slave %u does not exist!\n", slave_position);
3502 EC_SLAVE_DBG(slave, 1,
"Scheduling SDO download request.\n");
3511 request.
state != EC_INT_REQUEST_QUEUED)) {
3514 if (request.
state == EC_INT_REQUEST_QUEUED) {
3515 list_del(&request.
list);
3529 if (request.
state == EC_INT_REQUEST_SUCCESS) {
3531 }
else if (request.
errno) {
3532 ret = -request.
errno;
3544 uint16_t slave_position, uint16_t index,
const uint8_t *data,
3545 size_t data_size, uint32_t *abort_code)
3552 " slave_position = %u, index = 0x%04X," 3553 " data = 0x%p, data_size = %zu, abort_code = 0x%p)\n",
3554 __func__, master, slave_position, index, data, data_size,
3570 memcpy(request.
data, data, data_size);
3574 if (ec_lock_down_interruptible(&master->
master_sem)) {
3581 EC_MASTER_ERR(master,
"Slave %u does not exist!\n", slave_position);
3586 EC_SLAVE_DBG(slave, 1,
"Scheduling SDO download request" 3587 " (complete access).\n");
3596 request.
state != EC_INT_REQUEST_QUEUED)) {
3599 if (request.
state == EC_INT_REQUEST_QUEUED) {
3600 list_del(&request.
list);
3614 if (request.
state == EC_INT_REQUEST_SUCCESS) {
3616 }
else if (request.
errno) {
3617 ret = -request.
errno;
3629 uint16_t index, uint8_t subindex, uint8_t *target,
3630 size_t target_size,
size_t *result_size, uint32_t *abort_code)
3637 " slave_position = %u, index = 0x%04X, subindex = 0x%02X," 3638 " target = 0x%p, target_size = %zu, result_size = 0x%p," 3639 " abort_code = 0x%p)\n",
3640 __func__, master, slave_position, index, subindex,
3641 target, target_size, result_size, abort_code);
3647 if (ec_lock_down_interruptible(&master->
master_sem)) {
3655 EC_MASTER_ERR(master,
"Slave %u does not exist!\n", slave_position);
3659 EC_SLAVE_DBG(slave, 1,
"Scheduling SDO upload request.\n");
3668 request.
state != EC_INT_REQUEST_QUEUED)) {
3671 if (request.
state == EC_INT_REQUEST_QUEUED) {
3672 list_del(&request.
list);
3686 if (request.
state != EC_INT_REQUEST_SUCCESS) {
3688 if (request.
errno) {
3689 ret = -request.
errno;
3695 EC_SLAVE_ERR(slave,
"%s(): Buffer too small.\n", __func__);
3712 uint16_t index, uint8_t *target,
3713 size_t target_size,
size_t *result_size, uint32_t *abort_code)
3720 " slave_position = %u, index = 0x%04X," 3721 " target = 0x%p, target_size = %zu, result_size = 0x%p," 3722 " abort_code = 0x%p)\n",
3723 __func__, master, slave_position, index,
3724 target, target_size, result_size, abort_code);
3730 if (ec_lock_down_interruptible(&master->
master_sem)) {
3738 EC_MASTER_ERR(master,
"Slave %u does not exist!\n", slave_position);
3742 EC_SLAVE_DBG(slave, 1,
"Scheduling SDO upload request (complete access).\n");
3751 request.
state != EC_INT_REQUEST_QUEUED)) {
3754 if (request.
state == EC_INT_REQUEST_QUEUED) {
3755 list_del(&request.
list);
3769 if (request.
state != EC_INT_REQUEST_SUCCESS) {
3771 if (request.
errno) {
3772 ret = -request.
errno;
3795 uint8_t drive_no, uint16_t idn, uint8_t *data,
size_t data_size,
3796 uint16_t *error_code)
3817 memcpy(request.
data, data, data_size);
3821 if (ec_lock_down_interruptible(&master->
master_sem)) {
3834 EC_SLAVE_DBG(slave, 1,
"Scheduling SoE write request.\n");
3843 request.
state != EC_INT_REQUEST_QUEUED)) {
3846 if (request.
state == EC_INT_REQUEST_QUEUED) {
3848 list_del(&request.
list);
3862 ret = request.
state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
3871 uint8_t drive_no, uint16_t idn, uint8_t *target,
size_t target_size,
3872 size_t *result_size, uint16_t *error_code)
3888 if (ec_lock_down_interruptible(&master->
master_sem)) {
3896 EC_MASTER_ERR(master,
"Slave %u does not exist!\n", slave_position);
3900 EC_SLAVE_DBG(slave, 1,
"Scheduling SoE read request.\n");
3909 request.
state != EC_INT_REQUEST_QUEUED)) {
3912 if (request.
state == EC_INT_REQUEST_QUEUED) {
3913 list_del(&request.
list);
3929 if (request.
state != EC_INT_REQUEST_SUCCESS) {
3936 EC_SLAVE_ERR(slave,
"%s(): Buffer too small.\n", __func__);
3955 unsigned int rt_slave_requests)
3963 " slave request by the application.\n");
3967 " slave request by the master.\n");
3978 if (ec_lock_down_interruptible(&master->
master_sem)) {
3997 uint16_t alias, uint16_t posn)
4011 list_for_each_entry(eoe, &master->
eoe_handlers, list) {
4012 if ((eoe->
slave == NULL) &&
4020 if (!(eoe = kmalloc(
sizeof(
ec_eoe_t), GFP_KERNEL))) {
4021 EC_MASTER_ERR(master,
"Failed to allocate EoE handler memory!\n");
4026 if ((res =
ec_eoe_init(master, eoe, alias, posn))) {
4042 uint16_t alias, uint16_t posn)
4054 list_for_each_entry(eoe, &master->
eoe_handlers, list) {
4056 list_del(&eoe->
list);
4072 int ec_master_obj_dict(
ec_master_t *master, uint8_t *data,
4073 size_t *data_size,
size_t buff_size)
4075 uint8_t sdo_req_cmd;
4076 uint8_t sdo_resp_cmd;
4078 uint8_t sdo_sub_index;
4079 uint16_t slave_posn;
4083 size_t total_value_size;
4085 uint8_t link_status;
4087 uint32_t abort_code;
4088 uint8_t resp_error = 0;
4091 EC_MASTER_DBG(master, 1,
"MBox Gateway request for Master Information.\n");
4095 ((
EC_READ_U16(data + 5) & 0x0F) != EC_MBOX_TYPE_COE) ) {
4096 EC_MASTER_ERR(master,
"Master does not support requested mailbox type!\n");
4097 return -EPROTONOSUPPORT;
4104 EC_MASTER_ERR(master,
"Master only supports SDO requests!\n");
4110 sdo_req_cmd =
EC_READ_U8(data + offset) >> 5;
4112 sdo_sub_index =
EC_READ_U8(data + offset + 3);
4115 if (ec_lock_down_interruptible(&master->
master_sem)) {
4121 if ( (sdo_index >= 0x8000) && (sdo_index < 0x8000 + master->slave_count) ) {
4123 if (sdo_req_cmd != 0x02) {
4125 EC_MASTER_ERR(master,
"Master, unsupported SDO Command %hhu on" 4126 " 0x%04X:%02X!\n", sdo_req_cmd, sdo_index, sdo_sub_index);
4127 return -EPROTONOSUPPORT;
4131 slave_posn = sdo_index - 0x8000;
4136 EC_MASTER_ERR(master,
"Slave %u does not exist!\n", slave_posn);
4140 switch (sdo_sub_index) {
4144 value_size =
sizeof(uint8_t);
4150 value_size =
sizeof(uint16_t);
4156 memset(value, 0x00, value_size);
4164 memset(value, 0x00, value_size);
4176 value,
sizeof(uint32_t), &value_size, &abort_code) != 0)) {
4178 value_size =
sizeof(uint32_t);
4184 value_size =
sizeof(uint32_t);
4189 value_size =
sizeof(uint32_t);
4194 value_size =
sizeof(uint32_t);
4203 value_size =
sizeof(uint32_t);
4213 value_size =
sizeof(uint32_t);
4218 value_size =
sizeof(uint16_t);
4227 value_size =
sizeof(uint16_t);
4239 link_status += 1 << (4 + i);
4242 value_size =
sizeof(uint8_t);
4249 value_size =
sizeof(uint32_t);
4254 }
else if ( (sdo_index >= 0xA000) && (sdo_index < 0xA000 + master->slave_count) ) {
4259 slave_posn = sdo_index - 0xA000;
4261 switch (sdo_sub_index) {
4264 if (sdo_req_cmd != 0x02) {
4266 EC_MASTER_ERR(master,
"Master, unsupported SDO Command %hhu on" 4267 " 0x%04X:%02X!\n", sdo_req_cmd, sdo_index, sdo_sub_index);
4268 return -EPROTONOSUPPORT;
4272 value_size =
sizeof(uint8_t);
4280 if (sdo_req_cmd != 0x02) {
4282 EC_MASTER_ERR(master,
"Master, unsupported SDO Command %hhu on" 4283 " 0x%04X:%02X!\n", sdo_req_cmd, sdo_index, sdo_sub_index);
4284 return -EPROTONOSUPPORT;
4290 EC_MASTER_ERR(master,
"Slave %u does not exist!\n", slave_posn);
4298 value_size =
sizeof(uint16_t);
4306 if ( (sdo_req_cmd != 0x02) && (sdo_req_cmd != 0x00) ) {
4308 EC_MASTER_ERR(master,
"Master, unsupported SDO Command %hhu on" 4309 " 0x%04X:%02X!\n", sdo_req_cmd, sdo_index, sdo_sub_index);
4310 return -EPROTONOSUPPORT;
4316 EC_MASTER_ERR(master,
"Slave %u does not exist!\n", slave_posn);
4320 if (sdo_req_cmd == 0x02) {
4326 value_size =
sizeof(uint16_t);
4331 uint8_t *write_data = data + offset + 4;
4333 uint8_t size_specified =
EC_READ_U8(data + offset) & 0x01;
4334 if (size_specified) {
4335 write_size = 4 - ((
EC_READ_U8(data + offset) & 0x0C) >> 2);
4341 if (write_size != 2) {
4343 EC_MASTER_ERR(master,
"Master, unexpected SDO write data size" 4344 " %zu (expected %u) on 0x%04X:%02X!\n",
4345 write_size, 2, sdo_index, sdo_sub_index);
4346 return -EPROTONOSUPPORT;
4353 value_size =
sizeof(uint32_t);
4354 memset(value, 0x00, 4);
4360 value_size =
sizeof(uint32_t);
4365 }
else if ( (sdo_index >= 0xF020) && (sdo_index < 0xF030) ) {
4367 if (sdo_req_cmd != 0x02) {
4369 EC_MASTER_ERR(master,
"Master, unsupported SDO Command %hhu on" 4370 " 0x%04X:%02X!\n", sdo_req_cmd, sdo_index, sdo_sub_index);
4371 return -EPROTONOSUPPORT;
4374 if (sdo_sub_index == 0) {
4379 value_size =
sizeof(uint8_t);
4382 remainder = do_div(index, 255);
4384 if (sdo_index - 0xF020 < index) {
4386 }
else if ( (sdo_index - 0xF020 == index) && (remainder > 0) ) {
4393 slave_posn = ((sdo_index - 0xF020) << 8) + sdo_sub_index - (sdo_index - 0xF020 + 1);
4395 if (slave_posn < master->slave_count) {
4398 value_size =
sizeof(uint16_t);
4403 value_size =
sizeof(uint32_t);
4408 }
else if (sdo_index == 0xF000) {
4410 if (sdo_req_cmd != 0x02) {
4412 EC_MASTER_ERR(master,
"Master, unsupported SDO Command %hhu on" 4413 " 0x%04X:%02X!\n", sdo_req_cmd, sdo_index, sdo_sub_index);
4414 return -EPROTONOSUPPORT;
4418 switch (sdo_sub_index) {
4421 value_size =
sizeof(uint8_t);
4426 value_size =
sizeof(uint16_t);
4432 value_size =
sizeof(uint16_t);
4437 value_size =
sizeof(uint32_t);
4442 value_size =
sizeof(uint32_t);
4448 value_size =
sizeof(uint32_t);
4456 value_size =
sizeof(uint32_t);
4464 if ( (value_size > 0) && (value_size <= 4) ) {
4465 total_value_size = value_size;
4467 total_value_size = value_size +
sizeof(uint32_t);
4489 memcpy(data + offset + 4, value, value_size);
4496 if (sdo_req_cmd == 0x02) {
4498 sdo_resp_cmd = 0x02;
4501 sdo_resp_cmd = 0x01;
4506 if ( (value_size > 0) && (value_size <= 4) ) {
4513 ((4 - value_size) << 2) + 0x02 + 0x01);
4519 EC_WRITE_U8(data + offset, (sdo_resp_cmd << 5) + 0x01);
4526 offset +=
sizeof(uint32_t);
4530 memcpy(data + offset, value, value_size);
4540 int ec_master_mbox_gateway(
ec_master_t *master, uint8_t *data,
4541 size_t *data_size,
size_t buff_size)
4544 uint16_t slave_posn;
4552 if (slave_posn == 0)
4555 ret = ec_master_obj_dict(master, data, data_size, buff_size);
4572 if (ec_lock_down_interruptible(&master->
master_sem)) {
4581 EC_MASTER_ERR(master,
"Slave %u does not exist!\n", slave_posn);
4585 EC_SLAVE_DBG(slave, 1,
"Scheduling MBox Gateway request.\n");
4594 request.
state != EC_INT_REQUEST_QUEUED)) {
4597 if (request.
state == EC_INT_REQUEST_QUEUED) {
4598 list_del(&request.
list);
4610 if (request.
state != EC_INT_REQUEST_SUCCESS) {
4630 EC_MASTER_ERR(master,
"MBox Gateway: Invalid slave offset address %u!\n", slave_posn);
4645 list_for_each_entry(sc, &master->
configs, list) {
4689 EXPORT_SYMBOL(ecrt_master_eoe_addif);
4690 EXPORT_SYMBOL(ecrt_master_eoe_delif);
uint8_t * data
Mailbox response data.
ec_lock_t ext_queue_sem
Semaphore protecting the ext_datagram_queue.
void ec_eoe_queue(ec_eoe_t *eoe)
Queues the datagram, if necessary.
ec_mbox_data_t mbox_eoe_frag_data
Received mailbox data for EoE, type frame fragment.
struct list_head mbg_requests
EoE set IP parameter requests.
unsigned int injection_seq_fsm
Datagram injection sequence number for the FSM side.
uint32_t serial_number
Serial-Number stored on the slave.
void ec_master_clear_eoe_handlers(ec_master_t *master, unsigned int free_all)
Clear and free auto created EoE handlers.
#define EC_IO_TIMEOUT
Datagram timeout in microseconds.
ec_slave_port_desc_t desc
Physical port type.
unsigned int reserved
True, if the master is in use.
struct list_head ext_datagram_queue
Queue for non-application datagrams.
int ec_mac_is_zero(const uint8_t *)
uint16_t ring_position
Ring position.
uint32_t revision_number
Revision number.
unsigned long jiffies_sent
Jiffies, when the datagram was sent.
uint8_t upstream_port
Index of master-facing port.
void ec_master_clear_config(ec_master_t *master)
Clear the configuration applied by the application.
void ec_slave_calc_upstream_port(ec_slave_t *slave)
Calculates which of ports 0-3 appears to be the upstream one.
#define EC_ADDR_LEN
Size of the EtherCAT address field.
uint16_t ec_slave_sdo_count(const ec_slave_t *slave)
Get the number of SDOs in the dictionary.
void ecrt_sdo_request_index_complete(ec_sdo_request_t *req, uint16_t index)
Set the SDO index and prepare for complete-access.
ec_internal_request_state_t state
Request state.
void ec_soe_request_set_idn(ec_soe_request_t *req, uint16_t idn)
Set IDN.
int ec_rtdm_dev_init(ec_rtdm_dev_t *rtdm_dev, ec_master_t *master)
Initialize an RTDM device.
#define EC_DATAGRAM_NAME_SIZE
Size of the datagram description string.
uint32_t ecrt_master_sync_monitor_process(ec_master_t *master)
Processes the DC synchrony monitoring datagram.
size_t data_size
Size of the data in data.
uint8_t * data
Pointer to SDO data.
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.
struct list_head list
List item.
uint8_t sync_count
Number of sync managers.
char * ec_eoe_name(const ec_eoe_t *eoe)
Returns the eoe device name.
void ec_master_calc_dc(ec_master_t *master)
Distributed-clocks calculations.
unsigned int fsm_exec_count
Number of entries in execution list.
u64 last_loss
Tx/Rx difference of last statistics cycle.
void * pcap_curr_data
pcap debug output current memory pointer
u64 tx_count
Number of frames sent.
const unsigned int rate_intervals[]
List of intervals for statistics [s].
uint8_t error_flag
Error flag for that slave.
void ec_master_clear(ec_master_t *master)
Destructor.
EtherCAT Mailbox Gateway request.
struct list_head list
List item.
struct list_head sii_requests
SII write requests.
void ecrt_master_sync_slave_clocks(ec_master_t *master)
Queues the DC clock drift compensation datagram for sending.
#define EC_SLAVE_DBG(slave, level, fmt, args...)
Convenience macro for printing slave-specific debug messages to syslog.
size_t data_size
Size of the process data.
ec_mbox_data_t mbox_eoe_init_data
Received mailbox data for EoE, type eoe init reponse.
unsigned long jiffies_poll
jiffies of last poll
unsigned int reboot
Reboot requested.
ec_slave_t * slave
pointer to the corresponding slave
size_t data_size
Size of MBox request data.
void ec_master_queue_datagram_ext(ec_master_t *master, ec_datagram_t *datagram)
Places a datagram in the non-application datagram queue.
uint64_t app_time_sent
App time, when the datagram was sent.
OP (mailbox communication and input/output update)
s32 tx_byte_rates[EC_RATE_COUNT]
Transmit rates in byte/s for different statistics cycle periods.
uint16_t configured_tx_mailbox_offset
Configured send mailbox offset.
ec_internal_request_state_t state
State of the request.
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.
unsigned int slaves_responding[EC_MAX_NUM_DEVICES]
Number of responding slaves for every device.
void * pcap_data
pcap debug output memory pointer
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.
ec_slave_port_t ports[EC_MAX_PORTS]
Ports.
void ecrt_master_application_time(ec_master_t *master, uint64_t app_time)
Sets the application time.
void ec_fsm_master_reset(ec_fsm_master_t *fsm)
Reset state machine.
void ec_master_request_op(ec_master_t *master)
Request OP state for configured slaves.
static int ec_master_eoe_thread(void *)
Does the Ethernet over EtherCAT processing.
int ec_fsm_slave_is_ready(const ec_fsm_slave_t *fsm)
Returns, if the FSM is currently not busy and ready to execute.
unsigned int slave_count
Number of slaves in the bus.
ec_slave_state_t current_state
Current application state.
void ec_master_leave_operation_phase(ec_master_t *master)
Transition function from OPERATION to IDLE phase.
#define ec_master_num_devices(MASTER)
Number of Ethernet devices.
#define EC_RATE_COUNT
Number of statistic rate intervals to maintain.
Complete slave information interface data image.
ec_datagram_t sync_mon_datagram
Datagram used for DC synchronisation monitoring.
EtherCAT slave structure.
ec_internal_request_state_t state
SDO request state.
uint32_t vendor_id
Vendor-ID stored on the slave.
void ec_device_clear(ec_device_t *device)
Destructor.
ec_mbox_data_t mbox_mbg_data
Received mailbox data for MBox Gateway.
struct list_head list
List item.
ec_mbox_data_t mbox_foe_data
Received mailbox data for FoE.
struct list_head eoe_handlers
Ethernet over EtherCAT handlers.
uint32_t product_code
Slave product code.
ec_slave_port_link_t link
Port link state.
unsigned int slaves_responding
Sum of responding slaves on the given link.
int ec_master_thread_start(ec_master_t *master, int(*thread_func)(void *), const char *name)
Starts the master thread.
dev_t device_number
Device number for master cdevs.
ec_slave_port_link_t link
Port link status.
unsigned int allow_scan
True, if slave scanning is allowed.
size_t max_queue_size
Maximum size of datagram queue.
void ec_master_internal_receive_cb(void *cb_data)
Internal receiving callback.
uint16_t position
Index after alias.
unsigned int eoe_count
Number of EOE interfaces.
static int ec_master_operation_thread(void *)
Master kernel thread function for OPERATION phase.
void ec_soe_request_read(ec_soe_request_t *req)
Request a read operation.
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.
#define EC_FRAME_HEADER_SIZE
Size of an EtherCAT frame header.
void ecrt_master_callbacks(ec_master_t *master, void(*send_cb)(void *), void(*receive_cb)(void *), void *cb_data)
Sets the locking callbacks.
struct list_head list
List item.
uint32_t serial_number
Serial number.
int ecrt_master_get_slave(ec_master_t *master, uint16_t slave_position, ec_slave_info_t *slave_info)
Obtains slave information.
struct list_head fsm_exec_list
Slave FSM execution list.
void ec_master_expire_slave_config_requests(ec_master_t *master)
Abort active requests for slave configs without attached slaves.
char * order
Order number.
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.
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.
#define EC_WRITE_U8(DATA, VAL)
Write an 8-bit unsigned value to EtherCAT data.
uint32_t abort_code
SDO request abort code.
size_t ecrt_master_send_ext(ec_master_t *master)
Sends non-application datagrams.
u64 dc_ref_time
Common reference timestamp for DC start times.
ec_slave_state_t slave_states[EC_MAX_NUM_DEVICES]
AL states of responding slaves for every device.
struct list_head emerg_reg_requests
Emergency register access requests.
ec_internal_request_state_t state
Request state.
#define EC_COE_HEADER_SIZE
CoE header size.
char name[EC_DATAGRAM_NAME_SIZE]
Description of the datagram.
uint16_t alias
Slave alias.
void ec_device_update_stats(ec_device_t *device)
Update device statistics.
struct list_head domains
List of domains.
int ec_eoe_parse(const char *eoe, int *master_idx, uint16_t *alias, uint16_t *posn)
Parse an eoe interface from a string.
Finite state machine of an EtherCAT slave.
ec_datagram_t * datagram
Previous state datagram.
unsigned int link_up
true, if the given Ethernet link is up.
uint32_t delay_to_next_dc
Delay [ns] to next DC slave.
ec_fsm_slave_t fsm
Slave state machine.
#define EC_FIND_CONFIG
Common implementation for ec_master_get_config() and ec_master_get_config_const().
uint16_t error_code
SoE error code.
uint16_t working_counter
Working counter.
ec_domain_t * ecrt_master_create_domain(ec_master_t *master)
Creates a new process data domain.
uint8_t * data
Pointer to SDO data.
unsigned long jiffies
Jiffies of last statistic cycle.
unsigned int rt_slaves_available
if True, slave requests can be handled by calls to ecrt_master_exec_requests() from the applications ...
int16_t current_on_ebus
Power consumption in mA.
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.
uint8_t link_state
device link state
int ecrt_master_setup_domain_memory(ec_master_t *master)
setup the domain's process data memory.
static unsigned int debug_level
Debug level parameter.
u64 last_rx_count
Number of frames received of last statistics cycle.
uint8_t signal_detected
Detected signal on RX port.
const uint8_t * macs[EC_MAX_NUM_DEVICES]
Device MAC addresses.
Sent (still in the queue).
unsigned int slaves_responding
Sum of responding slaves on all Ethernet devices.
void ecrt_master_state(const ec_master_t *master, ec_master_state_t *state)
Reads the current master state.
Configured Address Physical Read.
wait_queue_head_t request_queue
Wait queue for external requests from user space.
void ec_master_clear_device_stats(ec_master_t *)
Clears the common device statistics.
void ecrt_master_sync_reference_clock_to(ec_master_t *master, uint64_t sync_time)
Queues the DC reference clock drift compensation datagram for sending.
uint16_t station_address
Configured station address.
const char * ec_device_names[2]
Device names.
unsigned int sync_count
Number of sync managers.
struct list_head list
List head.
void ec_slave_clear(ec_slave_t *slave)
Slave destructor.
ec_domain_t * ecrt_master_create_domain_err(ec_master_t *master)
Same as ecrt_master_create_domain(), but with ERR_PTR() return value.
unsigned int link_up
true, if the network link is up.
void ec_datagram_output_stats(ec_datagram_t *datagram)
Outputs datagram statistics at most every second.
int ec_master_enter_idle_phase(ec_master_t *master)
Transition function from ORPHANED to IDLE phase.
uint16_t std_rx_mailbox_size
Standard receive mailbox size.
ec_datagram_type_t type
Datagram type (APRD, BWR, etc.).
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.
void ecrt_slave_config_dc(ec_slave_config_t *sc, uint16_t assign_activate, uint32_t sync0_cycle_time, int32_t sync0_shift_time, uint32_t sync1_cycle_time, int32_t sync1_shift_time)
Configure distributed clocks.
struct ec_slave_info_t::@6 ports[EC_MAX_PORTS]
Port information.
Global definitions and macros.
uint32_t revision_number
Revision-Number stored on the slave.
EtherCAT master structure.
int ecrt_master_64bit_reference_clock_time(ec_master_t *master, uint64_t *time)
Get the 64bit dc reference slave clock time.
void * cb_data
Current callback data.
SAFEOP (mailbox communication and input update)
void ec_pdo_clear(ec_pdo_t *pdo)
PDO destructor.
void ec_device_send(ec_device_t *device, size_t size)
Sends the content of the transmit socket buffer.
ec_lock_t config_sem
Semaphore protecting the config_busy variable and the allow_config flag.
uint8_t * data
Pointer to MBox request data.
void ec_fsm_master_init(ec_fsm_master_t *fsm, ec_master_t *master, ec_datagram_t *datagram)
Constructor.
Initial state of a new datagram.
int ecrt_master_sdo_upload_complete(ec_master_t *master, uint16_t slave_position, uint16_t index, 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 via complete access.
#define EC_MASTER_DBG(master, level, fmt, args...)
Convenience macro for printing master-specific debug messages to syslog.
ec_slave_t * fsm_slave
Slave that is queried next for FSM exec.
unsigned int send_interval
Interval between two calls to ecrt_master_send().
ec_slave_t * slave
EtherCAT slave.
uint8_t loop_closed
Loop closed.
void ec_master_clear_sii_images(ec_master_t *master)
Clear the SII data applied during bus scanning.
uint8_t datagram_index
Current datagram index.
ec_lock_t device_sem
Device semaphore.
void ec_master_attach_slave_configs(ec_master_t *master)
Attaches the slave configurations to the slaves.
struct list_head datagram_queue
Datagram queue.
ec_slave_t * slave
slave the FSM runs on
void ecrt_sdo_request_read(ec_sdo_request_t *req)
Schedule an SDO read operation.
char name[EC_MAX_STRING_LENGTH]
Name of the slave.
void ec_sdo_request_clear(ec_sdo_request_t *req)
SDO request destructor.
struct task_struct * eoe_thread
EoE thread.
struct list_head sdo_requests
SDO access requests.
uint16_t error_code
MBox Gateway error code.
unsigned int unmatched
unmatched datagrams (received, but not queued any longer)
unsigned int auto_created
auto created flag.
unsigned int ext_ring_idx_fsm
Index in external datagram ring for FSM side.
void ec_datagram_zero(ec_datagram_t *datagram)
Fills the datagram payload memory with zeros.
#define EC_TX_RING_SIZE
Size of the transmit ring.
int ec_master_debug_level(ec_master_t *master, unsigned int level)
Set the debug level.
s32 tx_frame_rates[EC_RATE_COUNT]
Transmit rates in frames/s for different statistics cycle periods.
u8 dc_offset_valid
DC slaves have valid system time offsets.
uint64_t app_time
Application time.
ec_sii_image_t * sii_image
Current complete SII image.
s32 rx_byte_rates[EC_RATE_COUNT]
Receive rates in byte/s for different statistics cycle periods.
int ec_mbg_request_copy_data(ec_mbg_request_t *req, const uint8_t *source, size_t size)
Copies Mbox Gateway data from an external source.
Ethernet over EtherCAT (EoE)
struct list_head soe_requests
SoE requests.
#define EC_DATAGRAM_HEADER_SIZE
Size of an EtherCAT datagram header.
#define EC_MBG_SLAVE_ADDR_OFFSET
Mailbox Gateway, Mailbox header slave address offset.
ec_datagram_state_t state
State.
char * eoe_interfaces[MAX_EOE]
EOE interfaces parameter.
ec_device_stats_t device_stats
Device statistics.
ec_datagram_t fsm_datagram
Datagram used for state machines.
ec_slave_config_t * config
Current configuration.
ec_master_phase_t phase
Master phase.
#define EC_WRITE_U32(DATA, VAL)
Write a 32-bit unsigned value to EtherCAT data.
ec_slave_t * slaves
Array of slaves on the bus.
void ec_domain_clear(ec_domain_t *domain)
Domain destructor.
void ec_soe_request_set_drive_no(ec_soe_request_t *req, uint8_t drive_no)
Set drive number.
void ec_slave_calc_port_delays(ec_slave_t *slave)
Calculates the port transmission delays.
int ec_domain_finish(ec_domain_t *domain, uint32_t base_address)
Finishes a domain.
static unsigned long ext_injection_timeout_jiffies
Timeout for external datagram injection [jiffies].
int ec_eoe_is_idle(const ec_eoe_t *eoe)
Returns the idle state.
uint16_t mailbox_protocols
Supported mailbox protocols.
ec_domain_t * ec_master_find_domain(ec_master_t *master, unsigned int index)
Get a domain via its position in the list.
size_t data_size
Size of SDO data.
ec_datagram_t sync64_datagram
Datagram used to retrieve 64bit ref slave system clock time.
unsigned int timeouts
datagram timeouts
unsigned int debug_level
Master debug level.
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.
#define EC_SLAVE_ERR(slave, fmt, args...)
Convenience macro for printing slave-specific errors to syslog.
unsigned int ec_master_domain_count(const ec_master_t *master)
Get the number of domains.
struct list_head list
List item.
s32 loss_rates[EC_RATE_COUNT]
Frame loss rates for different statistics cycle periods.
unsigned int corrupted
corrupted frames
u64 last_tx_count
Number of frames sent of last statistics cycle.
uint32_t transmission_delay
DC system time transmission delay (offset from reference clock).
int ecrt_master_select_reference_clock(ec_master_t *master, ec_slave_config_t *sc)
Selects the reference clock for distributed clocks.
void ec_master_exec_slave_fsms(ec_master_t *master)
Execute slave FSMs.
void ec_soe_request_clear(ec_soe_request_t *req)
SoE request destructor.
unsigned int ext_ring_idx_rt
Index in external datagram ring for RT side.
unsigned int slave_count
Number of slaves on the bus.
unsigned int scan_busy
Current scan state.
ec_device_index_t
Master devices.
void(* receive_cb)(void *)
Current receive datagrams callback.
uint16_t dc_assign_activate
Vendor-specific AssignActivate word.
s32 rx_frame_rates[EC_RATE_COUNT]
Receive rates in frames/s for different statistics cycle periods.
uint16_t alias
Configured station alias.
#define EC_WRITE_U16(DATA, VAL)
Write a 16-bit unsigned value to EtherCAT data.
unsigned int index
Index (just a number).
void ec_slave_calc_transmission_delays_rec(ec_slave_t *slave, uint32_t *delay)
Recursively calculates transmission delays.
void ec_master_leave_idle_phase(ec_master_t *master)
Transition function from IDLE to ORPHANED phase.
EoE Init, Set IP Parameter Request.
unsigned int skip_count
Number of requeues when not yet received.
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)
Master constructor.
#define EC_READ_U32(DATA)
Read a 32-bit unsigned value from EtherCAT data.
#define EOE_STH_PENDING
return flag from ecrt_master_eoe_process() to indicate there is something still pending.
int ec_device_init(ec_device_t *device, ec_master_t *master)
Constructor.
ec_slave_port_desc_t desc
Port descriptors.
#define EC_MASTER_WARN(master, fmt, args...)
Convenience macro for printing master-specific warnings to syslog.
int ec_fsm_slave_exec(ec_fsm_slave_t *fsm, ec_datagram_t *datagram)
Executes the current state of the state machine.
unsigned int rt_slave_requests
if True, slave requests are to be handled by calls to ecrt_master_exec_requests() from the applicatio...
unsigned int active
Master has been activated.
unsigned int string_count
Number of SII strings.
struct list_head sent
Master list item for sent datagrams.
void ecrt_master_exec_slave_requests(ec_master_t *master)
Explicit call to process slave requests.
int ec_datagram_brd(ec_datagram_t *datagram, uint16_t mem_address, size_t data_size)
Initializes an EtherCAT BRD datagram.
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.
int ec_master_enter_operation_phase(ec_master_t *master)
Transition function from IDLE to OPERATION phase.
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.
uint8_t has_dc_system_time
The slave supports the DC system time register.
char ** strings
Strings in SII categories.
wait_queue_head_t scan_queue
Queue for processes that wait for slave scanning.
ec_datagram_t sync_datagram
Datagram used for DC drift compensation.
#define EC_MASTER_ERR(master, fmt, args...)
Convenience macro for printing master-specific errors to syslog.
struct device * class_device
Master class device.
int ec_datagram_fprd(ec_datagram_t *datagram, uint16_t configured_address, uint16_t mem_address, size_t data_size)
Initializes an EtherCAT FPRD datagram.
EtherCAT datagram structure.
void ec_master_queue_datagram(ec_master_t *master, ec_datagram_t *datagram)
Places a datagram in the datagram queue.
int ec_slave_config_attach(ec_slave_config_t *sc)
Attaches the configuration to the addressed slave object.
CANopen dictionary request.
static int ec_master_idle_thread(void *)
Master kernel thread function for IDLE phase.
unsigned int scan_busy
true, if a slave rescan is in progress
struct list_head configs
List of slave configurations.
ec_slave_t * slave
Slave pointer.
ec_slave_config_t * dc_ref_config
Application-selected DC reference clock slave config.
ec_device_index_t device_index
Device via which the datagram shall be / was sent.
void ec_mbg_request_init(ec_mbg_request_t *req)
Mbox Gateway request constructor.
int ec_soe_request_alloc(ec_soe_request_t *req, size_t size)
Pre-allocates the data memory.
void ec_sync_clear(ec_sync_t *sync)
Destructor.
void ecrt_master_reset(ec_master_t *master)
Retry configuring slaves.
#define EC_MBOX_HEADER_SIZE
Mailbox header size.
int ec_fsm_master_idle(const ec_fsm_master_t *fsm)
void ec_master_clear_slaves(ec_master_t *master)
Clear all slaves.
void ecrt_master_sync_monitor_queue(ec_master_t *master)
Queues the DC synchrony monitoring datagram for sending.
struct list_head list
list item
void ecrt_master_deactivate_slaves(ec_master_t *master)
Deactivates the slaves distributed clocks and sends the slaves into PREOP.
struct list_head list
List item.
void ec_mbg_request_clear(ec_mbg_request_t *req)
Mbox Gateway request destructor.
uint8_t * ec_device_tx_data(ec_device_t *device)
Returns a pointer to the device's transmit memory.
u64 last_rx_bytes
Number of bytes received of last statistics cycle.
unsigned long output_jiffies
time of last output
ec_stats_t stats
Cyclic statistics.
void ec_print_data(const uint8_t *, size_t)
Outputs frame contents for debugging purposes.
void ec_read_mbox_lock_clear(ec_slave_t *slave)
Clears the mailbox lock.
uint8_t valid_mbox_data
Received mailbox data is valid.
void ec_master_update_device_stats(ec_master_t *)
Updates the common device statistics.
int ec_datagram_prealloc(ec_datagram_t *datagram, size_t size)
Allocates internal payload memory.
uint16_t effective_alias
Effective alias address.
void ec_master_calc_transmission_delays(ec_master_t *master)
Calculates the bus transmission delays.
uint8_t al_state
Current state of the slave.
size_t data_size
Size of SDO data.
ec_lock_t master_sem
Master semaphore.
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.
uint8_t ready
The slave is ready for external requests.
uint8_t scan_busy
true, while the master is scanning the bus
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.
#define EC_READ_U16(DATA)
Read a 16-bit unsigned value from EtherCAT data.
void ec_master_eoe_start(ec_master_t *master)
Starts Ethernet over EtherCAT processing on demand.
u64 tx_bytes
Number of bytes sent.
void(* app_send_cb)(void *)
Application's send datagrams callback.
size_t ec_master_send_datagrams(ec_master_t *master, ec_device_index_t device_index)
Sends the datagrams in the queue for a certain device.
void * app_cb_data
Application callback data.
int ecrt_master_activate(ec_master_t *master)
Finishes the configuration phase and prepares for cyclic operation.
uint16_t ec_master_eoe_handler_count(const ec_master_t *master)
Get the number of EoE handlers.
int16_t current_on_ebus
Used current in mA.
void ec_master_clear_slave_configs(ec_master_t *)
Clear all slave configurations.
void ec_master_clear_domains(ec_master_t *)
Clear all domains.
void ec_master_find_dc_ref_clock(ec_master_t *)
Finds the DC reference clock.
size_t ecrt_master_send(ec_master_t *master)
Sends all datagrams in the queue.
struct list_head list
Used for execution list.
uint8_t scan_required
The slave is being scanned.
void ec_master_thread_stop(ec_master_t *master)
Stops the master thread.
void ec_sdo_request_init(ec_sdo_request_t *req)
SDO request constructor.
#define EC_MAX_PORTS
Maximum number of slave ports.
ec_datagram_t * ec_master_get_external_datagram(ec_master_t *master)
Searches for a free datagram in the external datagram ring.
ec_datagram_t ext_datagram_ring[EC_EXT_RING_SIZE]
External datagram ring.
uint16_t sdo_count
Number of SDOs.
struct list_head list
List item.
#define EC_MAX_STRING_LENGTH
Maximum string length.
void ec_datagram_init(ec_datagram_t *datagram)
Constructor.
static unsigned long timeout_jiffies
Frame timeout in jiffies.
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.
void ec_rtdm_dev_clear(ec_rtdm_dev_t *rtdm_dev)
Clear an RTDM device.
void ec_cdev_clear(ec_cdev_t *cdev)
Destructor.
ec_slave_t * next_slave
Connected slaves.
unsigned int link_up
true, if at least one Ethernet link is up.
uint32_t vendor_id
Slave vendor ID.
uint32_t receive_time
Port receive times for delay measurement.
wait_queue_head_t config_queue
Queue for processes that wait for slave configuration.
#define EC_EXT_RING_SIZE
Size of the external datagram ring.
void ec_master_reboot_slaves(ec_master_t *master)
Requests that all slaves on this master be rebooted (if supported).
void ec_master_internal_send_cb(void *cb_data)
Internal sending callback.
uint16_t next_slave
Ring position of next DC slave on that port.
void ec_master_calc_topology(ec_master_t *master)
Calculates the bus topology.
u64 app_time
Time of the last ecrt_master_sync() call.
void ec_slave_request_state(ec_slave_t *slave, ec_slave_state_t state)
Request a slave state and resets the error flag.
ec_mbox_data_t mbox_voe_data
Received mailbox data for VoE.
ec_datagram_t ref_sync_datagram
Datagram used for synchronizing the reference clock to the master clock.
void ec_master_output_stats(ec_master_t *master)
Output master statistics.
uint8_t base_dc_supported
Distributed clocks are supported.
#define EC_FIND_DOMAIN
Common implementation for ec_master_find_domain() and ec_master_find_domain_const().
u64 rx_count
Number of frames received.
void ecrt_master_deactivate(ec_master_t *master)
Deactivates the master.
unsigned int al_states
Application-layer states of all slaves.
uint8_t upstream_port
Index of upstream (master facing) port.
uint8_t * data
Datagram payload.
#define EC_FIND_SLAVE
Common implementation for ec_master_find_slave() and ec_master_find_slave_const().
#define EC_BYTE_TRANSMISSION_TIME_NS
Time to send a byte in nanoseconds.
uint16_t alias
The slaves alias if not equal to 0.
int ecrt_master(ec_master_t *master, ec_master_info_t *master_info)
Obtains master information.
void ec_eoe_run(ec_eoe_t *eoe)
Runs the EoE state machine.
#define EC_READ_U8(DATA)
Read an 8-bit unsigned value from EtherCAT data.
void ec_dict_request_init(ec_dict_request_t *req)
Dictionary request constructor.
int ecrt_master_write_idn(ec_master_t *master, uint16_t slave_position, uint8_t drive_no, uint16_t idn, uint8_t *data, size_t data_size, uint16_t *error_code)
Executes an SoE write request.
struct list_head dict_requests
Dictionary read requests.
void ec_master_slaves_not_available(ec_master_t *master)
Set flag to say that the slaves are not available for slave request processing.
EtherCAT slave configuration.
struct list_head queue
Master datagram queue item.
uint32_t product_code
Product-Code stored on the slave.
EtherCAT device structure.
void(* app_receive_cb)(void *)
Application's receive datagrams callback.
unsigned long pcap_size
Pcap buffer size in bytes.
void ec_soe_request_write(ec_soe_request_t *req)
Request a write operation.
struct net_device * dev
pointer to the assigned net_device
int ec_fsm_master_exec(ec_fsm_master_t *fsm)
Executes the current state of the state machine.
void ec_soe_request_init(ec_soe_request_t *req)
SoE request constructor.
EtherCAT slave configuration structure.
ec_sii_t sii
Extracted SII data.
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.
ec_device_index_t device_index
Index of device the slave responds on.
void ec_device_poll(ec_device_t *device)
Calls the poll function of the assigned net_device.
void ec_eoe_clear_slave(ec_eoe_t *eoe)
EoE clear slave.
void ec_eoe_clear(ec_eoe_t *eoe)
EoE destructor.
int ecrt_master_reference_clock_time(ec_master_t *master, uint32_t *time)
Get the lower 32 bit of the reference clock system time.
Unused and should not be queued (dequeued).
unsigned int ec_master_config_count(const ec_master_t *master)
Get the number of slave configurations provided by the application.
void ecrt_master_64bit_reference_clock_time_queue(ec_master_t *master)
Queues the 64bit dc reference slave clock time value datagram for sending.
Error while sending/receiving (dequeued).
Auto Increment Physical Write.
uint8_t address[EC_ADDR_LEN]
Recipient address.
u64 last_tx_bytes
Number of bytes sent of last statistics cycle.
int ec_sdo_request_alloc(ec_sdo_request_t *req, size_t size)
Pre-allocates the data memory.
uint32_t product_code
Vendor-specific product code.
void ec_domain_init(ec_domain_t *domain, ec_master_t *master, unsigned int index)
Domain constructor.
PREOP state (mailbox communication, no IO)
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.
void ec_slave_config_clear(ec_slave_config_t *sc)
Slave configuration destructor.
struct list_head list
List item.
Ethernet over EtherCAT (EoE) handler.
ec_fsm_master_t fsm
Master state machine.
ec_cdev_t cdev
Master character device.
u64 rx_bytes
Number of bytes received.
#define EC_DATAGRAM_FOOTER_SIZE
Size of an EtherCAT datagram footer.
uint8_t scan_required
Scan required.
unsigned int al_states
Application-layer states of the slaves on the given link.
#define EC_MASTER_INFO(master, fmt, args...)
Convenience macro for printing master-specific information to syslog.
unsigned int error_flag
Stop processing after an error.
uint16_t position
Offset of the slave in the ring.
ec_sync_t * syncs
SYNC MANAGER categories.
uint16_t std_tx_mailbox_size
Standard transmit mailbox size.
uint32_t receive_time
Receive time on DC transmission delay measurement.
int ec_master_calc_topology_rec(ec_master_t *master, ec_slave_t *upstream_slave, unsigned int *slave_position)
Calculates the bus topology; recursion function.
unsigned int config_changed
The configuration changed.
unsigned int injection_seq_rt
Datagram injection sequence number for the realtime side.
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.
Configured Address Physical Write.
ec_slave_state_t requested_state
Requested application state.
#define FORCE_OUTPUT_CORRUPTED
Always output corrupted frames.
#define EC_READ_U64(DATA)
Read a 64-bit unsigned value from EtherCAT data.
uint8_t index
Index (set by master).
void ecrt_master_sync_reference_clock(ec_master_t *master)
Queues the DC reference clock drift compensation datagram for sending.
uint8_t link_up
Link detected.
ec_device_t devices[EC_MAX_NUM_DEVICES]
EtherCAT devices.
void ec_slave_config_load_default_sync_config(ec_slave_config_t *sc)
Loads the default PDO assignment from the slave object.
ec_lock_t scan_sem
Semaphore protecting the scan_busy variable and the allow_scan flag.
unsigned int config_busy
State of slave configuration.
void ecrt_sdo_request_write(ec_sdo_request_t *req)
Schedule an SDO write operation.
void ec_master_inject_external_datagrams(ec_master_t *master)
Injects external datagrams that fit into the datagram queue.
ec_lock_t io_sem
Semaphore used in IDLE phase.
void ec_fsm_master_clear(ec_fsm_master_t *fsm)
Destructor.
int ec_eoe_is_open(const ec_eoe_t *eoe)
Returns the state of the device.
void ec_device_clear_stats(ec_device_t *device)
Clears the frame statistics.
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...
unsigned long jiffies_received
Jiffies, when the datagram was received.
ec_mbox_data_t mbox_coe_data
Received mailbox data for CoE.
void ec_slave_config_expire_disconnected_requests(ec_slave_config_t *sc)
Expires any requests that have been started on a detached slave.
ec_mbox_data_t mbox_soe_data
Received mailbox data for SoE.
size_t payload_size
Size of the mailbox response payload data.
void ec_master_eoe_stop(ec_master_t *master)
Stops the Ethernet over EtherCAT processing.
void(* send_cb)(void *)
Current send datagrams callback.
uint32_t vendor_id
Vendor ID.
uint32_t delay_to_next_dc
Delay to next slave with DC support behind this port [ns].
struct task_struct * thread
Master thread.
unsigned int queue_datagram
the datagram is ready for queuing
void ecrt_sdo_request_index(ec_sdo_request_t *req, uint16_t index, uint8_t subindex)
Set the SDO index and subindex and prepare for non-complete-access.
ec_slave_t * dc_ref_clock
DC reference clock slave.
int ec_cdev_init(ec_cdev_t *cdev, ec_master_t *master, dev_t dev_num)
Constructor.
struct list_head pdos
SII [RT]XPDO categories.
unsigned int force_config
Force (re-)configuration.
struct list_head sii_images
List of slave SII images.
#define EOE_STH_TO_SEND
return flag from ecrt_master_eoe_process() to indicate there is something to send.
int ecrt_master_rt_slave_requests(ec_master_t *master, unsigned int rt_slave_requests)
Selects whether to process slave requests by the application or the master.
void ec_sii_image_clear(ec_sii_image_t *sii_image)
Clear the SII data.
#define EC_SDO_INJECTION_TIMEOUT
SDO injection timeout in microseconds.
void ecrt_master_receive(ec_master_t *master)
Fetches received frames from the hardware and processes the datagrams.
#define EC_MAX_DATA_SIZE
Resulting maximum data size of a single datagram in a frame.
Sercos-over-EtherCAT request.
void ec_master_init_static(void)
Static variables initializer.
int ec_eoe_init(ec_master_t *master, ec_eoe_t *eoe, uint16_t alias, uint16_t ring_position)
EoE explicit init constructor.
ec_internal_request_state_t state
SDO request state.
void ec_mbg_request_run(ec_mbg_request_t *req)
Request to run.
void ec_master_slaves_available(ec_master_t *master)
Set flag to say that the slaves are now available for slave request processing.
void ec_datagram_clear(ec_datagram_t *datagram)
Destructor.