IgH EtherCAT Master  1.5.2
datagram.c
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  * $Id$
4  *
5  * Copyright (C) 2006-2008 Florian Pose, Ingenieurgemeinschaft IgH
6  *
7  * This file is part of the IgH EtherCAT Master.
8  *
9  * The IgH EtherCAT Master is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License version 2, as
11  * published by the Free Software Foundation.
12  *
13  * The IgH EtherCAT Master is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
16  * Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License along
19  * with the IgH EtherCAT Master; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21  *
22  * ---
23  *
24  * The license mentioned above concerns the source code only. Using the
25  * EtherCAT technology and brand is only permitted in compliance with the
26  * industrial property and similar rights of Beckhoff Automation GmbH.
27  *
28  *****************************************************************************/
29 
35 /*****************************************************************************/
36 
37 #include <linux/slab.h>
38 
39 #include "datagram.h"
40 #include "master.h"
41 
42 /*****************************************************************************/
43 
46 #define EC_FUNC_HEADER \
47  ret = ec_datagram_prealloc(datagram, data_size); \
48  if (unlikely(ret)) \
49  return ret; \
50  datagram->index = 0; \
51  datagram->working_counter = 0; \
52  datagram->state = EC_DATAGRAM_INIT;
53 
54 #define EC_FUNC_FOOTER \
55  datagram->data_size = data_size; \
56  return 0;
57 
60 /*****************************************************************************/
61 
66 static const char *type_strings[] = {
67  "?",
68  "APRD",
69  "APWR",
70  "APRW",
71  "FPRD",
72  "FPWR",
73  "FPRW",
74  "BRD",
75  "BWR",
76  "BRW",
77  "LRD",
78  "LWR",
79  "LRW",
80  "ARMW",
81  "FRMW"
82 };
83 
84 /*****************************************************************************/
85 
89 {
90  INIT_LIST_HEAD(&datagram->queue); // mark as unqueued
91  datagram->device_index = EC_DEVICE_MAIN;
92  datagram->type = EC_DATAGRAM_NONE;
93  memset(datagram->address, 0x00, EC_ADDR_LEN);
94  datagram->data = NULL;
95  datagram->data_origin = EC_ORIG_INTERNAL;
96  datagram->mem_size = 0;
97  datagram->data_size = 0;
98  datagram->index = 0x00;
99  datagram->working_counter = 0x0000;
100  datagram->state = EC_DATAGRAM_INIT;
101 #ifdef EC_HAVE_CYCLES
102  datagram->cycles_sent = 0;
103 #endif
104  datagram->jiffies_sent = 0;
105  datagram->app_time_sent = 0;
106 #ifdef EC_HAVE_CYCLES
107  datagram->cycles_received = 0;
108 #endif
109  datagram->jiffies_received = 0;
110  datagram->skip_count = 0;
111  datagram->stats_output_jiffies = 0;
112  memset(datagram->name, 0x00, EC_DATAGRAM_NAME_SIZE);
113 }
114 
115 /*****************************************************************************/
116 
120 {
121  ec_datagram_unqueue(datagram);
122 
123  if (datagram->data_origin == EC_ORIG_INTERNAL && datagram->data) {
124  kfree(datagram->data);
125  datagram->data = NULL;
126  }
127 }
128 
129 /*****************************************************************************/
130 
134 {
135  if (!list_empty(&datagram->queue)) {
136  list_del_init(&datagram->queue);
137  }
138 }
139 
140 /*****************************************************************************/
141 
152  ec_datagram_t *datagram,
153  size_t size
154  )
155 {
156  if (datagram->data_origin == EC_ORIG_EXTERNAL
157  || size <= datagram->mem_size)
158  return 0;
159 
160  if (datagram->data) {
161  kfree(datagram->data);
162  datagram->data = NULL;
163  datagram->mem_size = 0;
164  }
165 
166  if (!(datagram->data = kmalloc(size, GFP_KERNEL))) {
167  EC_ERR("Failed to allocate %zu bytes of datagram memory!\n", size);
168  return -ENOMEM;
169  }
170 
171  datagram->mem_size = size;
172  return 0;
173 }
174 
175 /*****************************************************************************/
176 
180 {
181  memset(datagram->data, 0x00, datagram->data_size);
182 }
183 
184 /*****************************************************************************/
185 
191  ec_datagram_t *datagram,
192  const ec_datagram_t *source )
193 {
194  int ret;
195  size_t data_size = source->data_size;
196  EC_FUNC_HEADER;
197  if (datagram != source) {
198  datagram->type = source->type;
199  memcpy(datagram->address, source->address, sizeof(datagram->address));
200  memcpy(datagram->data, source->data, data_size);
201  }
202  EC_FUNC_FOOTER;
203 }
204 
205 /*****************************************************************************/
206 
212  ec_datagram_t *datagram,
213  uint16_t ring_position,
214  uint16_t mem_address,
215  size_t data_size
216  )
217 {
218  int ret;
219  EC_FUNC_HEADER;
220  datagram->type = EC_DATAGRAM_APRD;
221  EC_WRITE_S16(datagram->address, (int16_t) ring_position * (-1));
222  EC_WRITE_U16(datagram->address + 2, mem_address);
223  EC_FUNC_FOOTER;
224 }
225 
226 /*****************************************************************************/
227 
233  ec_datagram_t *datagram,
234  uint16_t ring_position,
235  uint16_t mem_address,
236  size_t data_size
237  )
238 {
239  int ret;
240  EC_FUNC_HEADER;
241  datagram->type = EC_DATAGRAM_APWR;
242  EC_WRITE_S16(datagram->address, (int16_t) ring_position * (-1));
243  EC_WRITE_U16(datagram->address + 2, mem_address);
244  EC_FUNC_FOOTER;
245 }
246 
247 /*****************************************************************************/
248 
254  ec_datagram_t *datagram,
255  uint16_t ring_position,
256  uint16_t mem_address,
257  size_t data_size
258  )
259 {
260  int ret;
261  EC_FUNC_HEADER;
262  datagram->type = EC_DATAGRAM_APRW;
263  EC_WRITE_S16(datagram->address, (int16_t) ring_position * (-1));
264  EC_WRITE_U16(datagram->address + 2, mem_address);
265  EC_FUNC_FOOTER;
266 }
267 
268 /*****************************************************************************/
269 
275  ec_datagram_t *datagram,
276  uint16_t ring_position,
277  uint16_t mem_address,
278  size_t data_size
279  )
280 {
281  int ret;
282  EC_FUNC_HEADER;
283  datagram->type = EC_DATAGRAM_ARMW;
284  EC_WRITE_S16(datagram->address, (int16_t) ring_position * (-1));
285  EC_WRITE_U16(datagram->address + 2, mem_address);
286  EC_FUNC_FOOTER;
287 }
288 
289 /*****************************************************************************/
290 
296  ec_datagram_t *datagram,
297  uint16_t configured_address,
298  uint16_t mem_address,
299  size_t data_size
300  )
301 {
302  int ret;
303 
304  if (unlikely(configured_address == 0x0000))
305  EC_WARN("Using configured station address 0x0000!\n");
306 
307  EC_FUNC_HEADER;
308  datagram->type = EC_DATAGRAM_FPRD;
309  EC_WRITE_U16(datagram->address, configured_address);
310  EC_WRITE_U16(datagram->address + 2, mem_address);
311  EC_FUNC_FOOTER;
312 }
313 
314 /*****************************************************************************/
315 
321  ec_datagram_t *datagram,
322  uint16_t configured_address,
323  uint16_t mem_address,
324  size_t data_size
325  )
326 {
327  int ret;
328 
329  if (unlikely(configured_address == 0x0000))
330  EC_WARN("Using configured station address 0x0000!\n");
331 
332  EC_FUNC_HEADER;
333  datagram->type = EC_DATAGRAM_FPWR;
334  EC_WRITE_U16(datagram->address, configured_address);
335  EC_WRITE_U16(datagram->address + 2, mem_address);
336  EC_FUNC_FOOTER;
337 }
338 
339 /*****************************************************************************/
340 
346  ec_datagram_t *datagram,
347  uint16_t configured_address,
348  uint16_t mem_address,
349  size_t data_size
350  )
351 {
352  int ret;
353 
354  if (unlikely(configured_address == 0x0000))
355  EC_WARN("Using configured station address 0x0000!\n");
356 
357  EC_FUNC_HEADER;
358  datagram->type = EC_DATAGRAM_FPRW;
359  EC_WRITE_U16(datagram->address, configured_address);
360  EC_WRITE_U16(datagram->address + 2, mem_address);
361  EC_FUNC_FOOTER;
362 }
363 
364 /*****************************************************************************/
365 
371  ec_datagram_t *datagram,
372  uint16_t configured_address,
373  uint16_t mem_address,
374  size_t data_size
375  )
376 {
377  int ret;
378 
379  if (unlikely(configured_address == 0x0000))
380  EC_WARN("Using configured station address 0x0000!\n");
381 
382  EC_FUNC_HEADER;
383  datagram->type = EC_DATAGRAM_FRMW;
384  EC_WRITE_U16(datagram->address, configured_address);
385  EC_WRITE_U16(datagram->address + 2, mem_address);
386  EC_FUNC_FOOTER;
387 }
388 
389 /*****************************************************************************/
390 
396  ec_datagram_t *datagram,
397  uint16_t mem_address,
398  size_t data_size
399  )
400 {
401  int ret;
402  EC_FUNC_HEADER;
403  datagram->type = EC_DATAGRAM_BRD;
404  EC_WRITE_U16(datagram->address, 0x0000);
405  EC_WRITE_U16(datagram->address + 2, mem_address);
406  EC_FUNC_FOOTER;
407 }
408 
409 /*****************************************************************************/
410 
416  ec_datagram_t *datagram,
417  uint16_t mem_address,
418  size_t data_size
419  )
420 {
421  int ret;
422  EC_FUNC_HEADER;
423  datagram->type = EC_DATAGRAM_BWR;
424  EC_WRITE_U16(datagram->address, 0x0000);
425  EC_WRITE_U16(datagram->address + 2, mem_address);
426  EC_FUNC_FOOTER;
427 }
428 
429 /*****************************************************************************/
430 
436  ec_datagram_t *datagram,
437  uint16_t mem_address,
438  size_t data_size
439  )
440 {
441  int ret;
442  EC_FUNC_HEADER;
443  datagram->type = EC_DATAGRAM_BRW;
444  EC_WRITE_U16(datagram->address, 0x0000);
445  EC_WRITE_U16(datagram->address + 2, mem_address);
446  EC_FUNC_FOOTER;
447 }
448 
449 /*****************************************************************************/
450 
456  ec_datagram_t *datagram,
457  uint32_t offset,
458  size_t data_size
459  )
460 {
461  int ret;
462  EC_FUNC_HEADER;
463  datagram->type = EC_DATAGRAM_LRD;
464  EC_WRITE_U32(datagram->address, offset);
465  EC_FUNC_FOOTER;
466 }
467 
468 /*****************************************************************************/
469 
475  ec_datagram_t *datagram,
476  uint32_t offset,
477  size_t data_size
478  )
479 {
480  int ret;
481  EC_FUNC_HEADER;
482  datagram->type = EC_DATAGRAM_LWR;
483  EC_WRITE_U32(datagram->address, offset);
484  EC_FUNC_FOOTER;
485 }
486 
487 /*****************************************************************************/
488 
494  ec_datagram_t *datagram,
495  uint32_t offset,
496  size_t data_size
497  )
498 {
499  int ret;
500  EC_FUNC_HEADER;
501  datagram->type = EC_DATAGRAM_LRW;
502  EC_WRITE_U32(datagram->address, offset);
503  EC_FUNC_FOOTER;
504 }
505 
506 /*****************************************************************************/
507 
516  ec_datagram_t *datagram,
517  uint32_t offset,
518  size_t data_size,
519  uint8_t *external_memory
520  )
521 {
522  int ret;
523  datagram->data = external_memory;
524  datagram->data_origin = EC_ORIG_EXTERNAL;
525  EC_FUNC_HEADER;
526  datagram->type = EC_DATAGRAM_LRD;
527  EC_WRITE_U32(datagram->address, offset);
528  EC_FUNC_FOOTER;
529 }
530 
531 /*****************************************************************************/
532 
541  ec_datagram_t *datagram,
542  uint32_t offset,
543  size_t data_size,
544  uint8_t *external_memory
545  )
546 {
547  int ret;
548  datagram->data = external_memory;
549  datagram->data_origin = EC_ORIG_EXTERNAL;
550  EC_FUNC_HEADER;
551  datagram->type = EC_DATAGRAM_LWR;
552  EC_WRITE_U32(datagram->address, offset);
553  EC_FUNC_FOOTER;
554 }
555 
556 /*****************************************************************************/
557 
566  ec_datagram_t *datagram,
567  uint32_t offset,
568  size_t data_size,
569  uint8_t *external_memory
570  )
571 {
572  int ret;
573  datagram->data = external_memory;
574  datagram->data_origin = EC_ORIG_EXTERNAL;
575  EC_FUNC_HEADER;
576  datagram->type = EC_DATAGRAM_LRW;
577  EC_WRITE_U32(datagram->address, offset);
578  EC_FUNC_FOOTER;
579 }
580 
581 /*****************************************************************************/
582 
588  const ec_datagram_t *datagram
589  )
590 {
591  printk(KERN_CONT "Datagram ");
592  switch (datagram->state) {
593  case EC_DATAGRAM_INIT:
594  printk(KERN_CONT "initialized");
595  break;
596  case EC_DATAGRAM_QUEUED:
597  printk(KERN_CONT "queued");
598  break;
599  case EC_DATAGRAM_SENT:
600  printk(KERN_CONT "sent");
601  break;
603  printk(KERN_CONT "received");
604  break;
606  printk(KERN_CONT "timed out");
607  break;
608  case EC_DATAGRAM_ERROR:
609  printk(KERN_CONT "error");
610  break;
611  case EC_DATAGRAM_INVALID:
612  printk(KERN_CONT "invalid");
613  break;
614  default:
615  printk(KERN_CONT "???");
616  }
617 
618  printk(KERN_CONT ".\n");
619 }
620 
621 /*****************************************************************************/
622 
628  const ec_datagram_t *datagram
629  )
630 {
631  if (datagram->working_counter == 0)
632  printk(KERN_CONT "No response.");
633  else if (datagram->working_counter > 1)
634  printk(KERN_CONT "%u slaves responded!", datagram->working_counter);
635  else
636  printk(KERN_CONT "Success.");
637  printk(KERN_CONT "\n");
638 }
639 
640 /*****************************************************************************/
641 
645  ec_datagram_t *datagram
646  )
647 {
648  if (jiffies - datagram->stats_output_jiffies > HZ) {
649  datagram->stats_output_jiffies = jiffies;
650 
651  if (unlikely(datagram->skip_count)) {
652  EC_WARN("Datagram %p (%s) was SKIPPED %u time%s.\n",
653  datagram, datagram->name,
654  datagram->skip_count,
655  datagram->skip_count == 1 ? "" : "s");
656  datagram->skip_count = 0;
657  }
658  }
659 }
660 
661 /*****************************************************************************/
662 
668  const ec_datagram_t *datagram
669  )
670 {
671  return type_strings[datagram->type];
672 }
673 
674 /*****************************************************************************/
675 
680  ec_mbox_data_t *mbox_data
681  )
682 {
683  mbox_data->data = NULL;
684  mbox_data->data_size = 0;
685  mbox_data->payload_size = 0;
686 }
687 
688 
689 /*****************************************************************************/
690 
695  ec_mbox_data_t *mbox_data
696  )
697 {
698  if (mbox_data->data) {
699  kfree(mbox_data->data);
700  mbox_data->data = NULL;
701  mbox_data->data_size = 0;
702  }
703 }
704 
705 
706 /*****************************************************************************/
707 
713  ec_mbox_data_t *mbox_data,
714  size_t size
715  )
716 {
717  if (mbox_data->data) {
718  kfree(mbox_data->data);
719  mbox_data->data = NULL;
720  mbox_data->data_size = 0;
721  }
722 
723  if (!(mbox_data->data = kmalloc(size, GFP_KERNEL))) {
724  EC_ERR("Failed to allocate %zu bytes of mailbox data memory!\n", size);
725  return -ENOMEM;
726  }
727  mbox_data->data_size = size;
728  return 0;
729 }
730 
731 
732 /*****************************************************************************/
733 
739  ec_slave_t *slave,
740  uint16_t protocols,
741  size_t size
742  )
743 {
744  if ((size > 0) && (size <= EC_MAX_DATA_SIZE)) {
745 #ifdef EC_EOE
746  if (protocols & EC_MBOX_EOE) {
749  } else {
752  }
753 #endif
754  if (protocols & EC_MBOX_COE) {
755  ec_mbox_data_prealloc(&slave->mbox_coe_data, size);
756  } else {
758  }
759  if (protocols & EC_MBOX_FOE) {
760  ec_mbox_data_prealloc(&slave->mbox_foe_data, size);
761  } else {
763  }
764  if (protocols & EC_MBOX_SOE) {
765  ec_mbox_data_prealloc(&slave->mbox_soe_data, size);
766  } else {
768  }
769  if (protocols & EC_MBOX_VOE) {
770  ec_mbox_data_prealloc(&slave->mbox_voe_data, size);
771  } else {
773  }
774 
775  // alloc mailbox gateway if slave supports any protocol
776  if (protocols) {
777  ec_mbox_data_prealloc(&slave->mbox_mbg_data, size);
778  } else {
780  }
781  }
782 }
783 
784 /*****************************************************************************/
uint8_t * data
Mailbox response data.
Definition: datagram.h:123
ec_mbox_data_t mbox_eoe_frag_data
Received mailbox data for EoE, type frame fragment.
Definition: slave.h:288
Vendor specific.
Definition: globals.h:187
#define EC_WARN(fmt, args...)
Convenience macro for printing EtherCAT-specific warnings to syslog.
Definition: globals.h:272
void ec_mbox_prot_data_prealloc(ec_slave_t *slave, uint16_t protocols, size_t size)
Allocates internal memory for mailbox response data for all slave supported mailbox protocols ...
Definition: datagram.c:738
unsigned long jiffies_sent
Jiffies, when the datagram was sent.
Definition: datagram.h:105
Auto Increment Physical Read Multiple Write.
Definition: datagram.h:64
#define EC_ADDR_LEN
Size of the EtherCAT address field.
Definition: globals.h:87
static const char * type_strings[]
Array of datagram type strings used in ec_datagram_type_string().
Definition: datagram.c:66
#define EC_DATAGRAM_NAME_SIZE
Size of the datagram description string.
Definition: globals.h:142
Auto Increment Physical ReadWrite.
Definition: datagram.h:54
size_t data_size
Size of the data in data.
Definition: datagram.h:98
void ec_mbox_data_init(ec_mbox_data_t *mbox_data)
Initialize mailbox response data.
Definition: datagram.c:679
Servo-Profile over EtherCAT.
Definition: globals.h:186
ec_mbox_data_t mbox_eoe_init_data
Received mailbox data for EoE, type eoe init reponse.
Definition: slave.h:289
Broadcast ReadWrite.
Definition: datagram.h:60
uint64_t app_time_sent
App time, when the datagram was sent.
Definition: datagram.h:106
unsigned long stats_output_jiffies
Last statistics output.
Definition: datagram.h:113
ec_mbox_data_t mbox_mbg_data
Received mailbox data for MBox Gateway.
Definition: slave.h:295
ec_mbox_data_t mbox_foe_data
Received mailbox data for FoE.
Definition: slave.h:292
ec_origin_t data_origin
Origin of the data memory.
Definition: datagram.h:96
int ec_datagram_lwr_ext(ec_datagram_t *datagram, uint32_t offset, size_t data_size, uint8_t *external_memory)
Initializes an EtherCAT LWR datagram with external memory.
Definition: datagram.c:540
EtherCAT mailbox response data.
Definition: datagram.h:122
EtherCAT datagram.
Definition: datagram.h:88
Logical Read.
Definition: datagram.h:61
char name[EC_DATAGRAM_NAME_SIZE]
Description of the datagram.
Definition: datagram.h:114
uint16_t working_counter
Working counter.
Definition: datagram.h:100
#define EC_WRITE_S16(DATA, VAL)
Write a 16-bit signed value to EtherCAT data.
Definition: ecrt.h:2669
Sent (still in the queue).
Definition: datagram.h:77
Configured Address Physical Read.
Definition: datagram.h:55
void ec_datagram_output_stats(ec_datagram_t *datagram)
Outputs datagram statistics at most every second.
Definition: datagram.c:644
int ec_datagram_lwr(ec_datagram_t *datagram, uint32_t offset, size_t data_size)
Initializes an EtherCAT LWR datagram.
Definition: datagram.c:474
int ec_datagram_aprd(ec_datagram_t *datagram, uint16_t ring_position, uint16_t mem_address, size_t data_size)
Initializes an EtherCAT APRD datagram.
Definition: datagram.c:211
ec_datagram_type_t type
Datagram type (APRD, BWR, etc.).
Definition: datagram.h:93
Logical Write.
Definition: datagram.h:62
EtherCAT master structure.
Internal.
Definition: globals.h:342
Initial state of a new datagram.
Definition: datagram.h:75
EtherCAT slave.
Definition: slave.h:214
int ec_datagram_apwr(ec_datagram_t *datagram, uint16_t ring_position, uint16_t mem_address, size_t data_size)
Initializes an EtherCAT APWR datagram.
Definition: datagram.c:232
void ec_datagram_zero(ec_datagram_t *datagram)
Fills the datagram payload memory with zeros.
Definition: datagram.c:179
ec_datagram_state_t state
State.
Definition: datagram.h:101
CANopen over EtherCAT.
Definition: globals.h:184
#define EC_WRITE_U32(DATA, VAL)
Write a 32-bit unsigned value to EtherCAT data.
Definition: ecrt.h:2676
size_t data_size
Size of the mailbox response data buffer.
Definition: datagram.h:124
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:370
void ec_datagram_print_wc_error(const ec_datagram_t *datagram)
Evaluates the working counter of a single-cast datagram.
Definition: datagram.c:627
#define EC_WRITE_U16(DATA, VAL)
Write a 16-bit unsigned value to EtherCAT data.
Definition: ecrt.h:2659
External.
Definition: globals.h:343
Main device.
Definition: globals.h:237
unsigned int skip_count
Number of requeues when not yet received.
Definition: datagram.h:112
Ethernet over EtherCAT.
Definition: globals.h:183
Auto Increment Physical Read.
Definition: datagram.h:52
int ec_datagram_brd(ec_datagram_t *datagram, uint16_t mem_address, size_t data_size)
Initializes an EtherCAT BRD datagram.
Definition: datagram.c:395
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:320
void ec_datagram_unqueue(ec_datagram_t *datagram)
Unqueue datagram.
Definition: datagram.c:133
int ec_datagram_lrd_ext(ec_datagram_t *datagram, uint32_t offset, size_t data_size, uint8_t *external_memory)
Initializes an EtherCAT LRD datagram with external memory.
Definition: datagram.c:515
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.
Definition: datagram.c:295
EtherCAT datagram structure.
Broadcast Write.
Definition: datagram.h:59
ec_device_index_t device_index
Device via which the datagram shall be / was sent.
Definition: datagram.h:91
int ec_datagram_aprw(ec_datagram_t *datagram, uint16_t ring_position, uint16_t mem_address, size_t data_size)
Initializes an EtherCAT APRW datagram.
Definition: datagram.c:253
int ec_datagram_lrd(ec_datagram_t *datagram, uint32_t offset, size_t data_size)
Initializes an EtherCAT LRD datagram.
Definition: datagram.c:455
int ec_datagram_fprw(ec_datagram_t *datagram, uint16_t configured_address, uint16_t mem_address, size_t data_size)
Initializes an EtherCAT FPRW datagram.
Definition: datagram.c:345
int ec_datagram_prealloc(ec_datagram_t *datagram, size_t size)
Allocates internal payload memory.
Definition: datagram.c:151
Configured Address Physical Read Multiple Write.
Definition: datagram.h:66
void ec_mbox_data_clear(ec_mbox_data_t *mbox_data)
Free internal memory for mailbox response data.
Definition: datagram.c:694
void ec_datagram_print_state(const ec_datagram_t *datagram)
Prints the state of a datagram.
Definition: datagram.c:587
#define EC_ERR(fmt, args...)
Convenience macro for printing EtherCAT-specific errors to syslog.
Definition: globals.h:262
int ec_datagram_brw(ec_datagram_t *datagram, uint16_t mem_address, size_t data_size)
Initializes an EtherCAT BRW datagram.
Definition: datagram.c:435
void ec_datagram_init(ec_datagram_t *datagram)
Constructor.
Definition: datagram.c:88
Queued for sending.
Definition: datagram.h:76
Logical ReadWrite.
Definition: datagram.h:63
Timed out (dequeued).
Definition: datagram.h:79
Broadcast Read.
Definition: datagram.h:58
ec_mbox_data_t mbox_voe_data
Received mailbox data for VoE.
Definition: slave.h:294
int ec_datagram_lrw_ext(ec_datagram_t *datagram, uint32_t offset, size_t data_size, uint8_t *external_memory)
Initializes an EtherCAT LRW datagram with external memory.
Definition: datagram.c:565
const char * ec_datagram_type_string(const ec_datagram_t *datagram)
Returns a string describing the datagram type.
Definition: datagram.c:667
uint8_t * data
Datagram payload.
Definition: datagram.h:95
Configured Address Physical ReadWrite.
Definition: datagram.h:57
struct list_head queue
Master datagram queue item.
Definition: datagram.h:89
size_t mem_size
Datagram data memory size.
Definition: datagram.h:97
Unused and should not be queued (dequeued).
Definition: datagram.h:81
Error while sending/receiving (dequeued).
Definition: datagram.h:80
Auto Increment Physical Write.
Definition: datagram.h:53
uint8_t address[EC_ADDR_LEN]
Recipient address.
Definition: datagram.h:94
Received (dequeued).
Definition: datagram.h:78
int ec_mbox_data_prealloc(ec_mbox_data_t *mbox_data, size_t size)
Allocates internal memory for mailbox response data.
Definition: datagram.c:712
Configured Address Physical Write.
Definition: datagram.h:56
uint8_t index
Index (set by master).
Definition: datagram.h:99
File-Access over EtherCAT.
Definition: globals.h:185
int ec_datagram_repeat(ec_datagram_t *datagram, const ec_datagram_t *source)
Copies a previously constructed datagram for repeated send.
Definition: datagram.c:190
int ec_datagram_lrw(ec_datagram_t *datagram, uint32_t offset, size_t data_size)
Initializes an EtherCAT LRW datagram.
Definition: datagram.c:493
unsigned long jiffies_received
Jiffies, when the datagram was received.
Definition: datagram.h:110
ec_mbox_data_t mbox_coe_data
Received mailbox data for CoE.
Definition: slave.h:291
ec_mbox_data_t mbox_soe_data
Received mailbox data for SoE.
Definition: slave.h:293
size_t payload_size
Size of the mailbox response payload data.
Definition: datagram.h:125
int ec_datagram_armw(ec_datagram_t *datagram, uint16_t ring_position, uint16_t mem_address, size_t data_size)
Initializes an EtherCAT ARMW datagram.
Definition: datagram.c:274
int ec_datagram_bwr(ec_datagram_t *datagram, uint16_t mem_address, size_t data_size)
Initializes an EtherCAT BWR datagram.
Definition: datagram.c:415
#define EC_MAX_DATA_SIZE
Resulting maximum data size of a single datagram in a frame.
Definition: globals.h:95
void ec_datagram_clear(ec_datagram_t *datagram)
Destructor.
Definition: datagram.c:119