29#include <linux/slab.h>
38#define EC_FUNC_HEADER \
39 ret = ec_datagram_prealloc(datagram, data_size); \
42 datagram->index = 0; \
43 datagram->working_counter = 0; \
44 datagram->state = EC_DATAGRAM_INIT;
46#define EC_FUNC_FOOTER \
47 datagram->data_size = data_size; \
82 INIT_LIST_HEAD(&datagram->
queue);
86 datagram->
data = NULL;
90 datagram->
index = 0x00;
94 datagram->cycles_sent = 0;
98 datagram->cycles_received = 0;
115 kfree(datagram->
data);
116 datagram->
data = NULL;
126 if (!list_empty(&datagram->
queue)) {
127 list_del_init(&datagram->
queue);
148 || size <= datagram->mem_size)
151 if (datagram->
data) {
152 kfree(datagram->
data);
153 datagram->
data = NULL;
157 if (!(datagram->
data = kmalloc(size, GFP_KERNEL))) {
158 EC_ERR(
"Failed to allocate %zu bytes of datagram memory!\n", size);
183 uint16_t ring_position,
184 uint16_t mem_address,
204 uint16_t ring_position,
205 uint16_t mem_address,
225 uint16_t ring_position,
226 uint16_t mem_address,
246 uint16_t ring_position,
247 uint16_t mem_address,
267 uint16_t configured_address,
268 uint16_t mem_address,
274 if (unlikely(configured_address == 0x0000))
275 EC_WARN(
"Using configured station address 0x0000!\n");
292 uint16_t configured_address,
293 uint16_t mem_address,
299 if (unlikely(configured_address == 0x0000))
300 EC_WARN(
"Using configured station address 0x0000!\n");
317 uint16_t configured_address,
318 uint16_t mem_address,
324 if (unlikely(configured_address == 0x0000))
325 EC_WARN(
"Using configured station address 0x0000!\n");
342 uint16_t configured_address,
343 uint16_t mem_address,
349 if (unlikely(configured_address == 0x0000))
350 EC_WARN(
"Using configured station address 0x0000!\n");
367 uint16_t mem_address,
387 uint16_t mem_address,
407 uint16_t mem_address,
489 uint8_t *external_memory
493 datagram->
data = external_memory;
514 uint8_t *external_memory
518 datagram->
data = external_memory;
539 uint8_t *external_memory
543 datagram->
data = external_memory;
561 printk(KERN_CONT
"Datagram ");
562 switch (datagram->
state) {
564 printk(KERN_CONT
"initialized");
567 printk(KERN_CONT
"queued");
570 printk(KERN_CONT
"sent");
573 printk(KERN_CONT
"received");
576 printk(KERN_CONT
"timed out");
579 printk(KERN_CONT
"error");
582 printk(KERN_CONT
"???");
585 printk(KERN_CONT
".\n");
599 printk(KERN_CONT
"No response.");
605 printk(KERN_CONT
"Success.");
607 printk(KERN_CONT
"\n");
622 EC_WARN(
"Datagram %p (%s) was SKIPPED %u time%s.\n",
623 datagram, datagram->
name,
int ec_datagram_brw(ec_datagram_t *datagram, uint16_t mem_address, size_t data_size)
Initializes an EtherCAT BRW datagram.
void ec_datagram_print_wc_error(const ec_datagram_t *datagram)
Evaluates the working counter of a single-cast datagram.
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.
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.
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.
int ec_datagram_prealloc(ec_datagram_t *datagram, size_t size)
Allocates internal payload memory.
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.
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.
void ec_datagram_zero(ec_datagram_t *datagram)
Fills the datagram payload memory with zeros.
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.
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.
int ec_datagram_brd(ec_datagram_t *datagram, uint16_t mem_address, size_t data_size)
Initializes an EtherCAT BRD datagram.
int ec_datagram_bwr(ec_datagram_t *datagram, uint16_t mem_address, size_t data_size)
Initializes an EtherCAT BWR datagram.
static const char * type_strings[]
Array of datagram type strings used in ec_datagram_type_string().
void ec_datagram_print_state(const ec_datagram_t *datagram)
Prints the state of a datagram.
void ec_datagram_output_stats(ec_datagram_t *datagram)
Outputs datagram statistics at most every second.
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.
const char * ec_datagram_type_string(const ec_datagram_t *datagram)
Returns a string describing the datagram type.
int ec_datagram_lwr(ec_datagram_t *datagram, uint32_t offset, size_t data_size)
Initializes an EtherCAT LWR datagram.
int ec_datagram_lrd(ec_datagram_t *datagram, uint32_t offset, size_t data_size)
Initializes an EtherCAT LRD datagram.
void ec_datagram_clear(ec_datagram_t *datagram)
Destructor.
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_datagram_lrw(ec_datagram_t *datagram, uint32_t offset, size_t data_size)
Initializes an EtherCAT LRW datagram.
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.
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.
void ec_datagram_unqueue(ec_datagram_t *datagram)
Unqueue datagram.
void ec_datagram_init(ec_datagram_t *datagram)
Constructor.
EtherCAT datagram structure.
@ EC_DATAGRAM_FPWR
Configured Address Physical Write.
@ EC_DATAGRAM_APRW
Auto Increment Physical ReadWrite.
@ EC_DATAGRAM_ARMW
Auto Increment Physical Read Multiple Write.
@ EC_DATAGRAM_FPRD
Configured Address Physical Read.
@ EC_DATAGRAM_APRD
Auto Increment Physical Read.
@ EC_DATAGRAM_BRD
Broadcast Read.
@ EC_DATAGRAM_LRW
Logical ReadWrite.
@ EC_DATAGRAM_BRW
Broadcast ReadWrite.
@ EC_DATAGRAM_LWR
Logical Write.
@ EC_DATAGRAM_FRMW
Configured Address Physical Read Multiple Write.
@ EC_DATAGRAM_FPRW
Configured Address Physical ReadWrite.
@ EC_DATAGRAM_BWR
Broadcast Write.
@ EC_DATAGRAM_APWR
Auto Increment Physical Write.
@ EC_DATAGRAM_LRD
Logical Read.
@ EC_DATAGRAM_INIT
Initial state of a new datagram.
@ EC_DATAGRAM_RECEIVED
Received (dequeued).
@ EC_DATAGRAM_TIMED_OUT
Timed out (dequeued).
@ EC_DATAGRAM_SENT
Sent (still in the queue).
@ EC_DATAGRAM_QUEUED
Queued for sending.
@ EC_DATAGRAM_ERROR
Error while sending/receiving (dequeued).
#define EC_WARN(fmt, args...)
Convenience macro for printing EtherCAT-specific warnings to syslog.
#define EC_ADDR_LEN
Size of the EtherCAT address field.
@ EC_ORIG_EXTERNAL
External.
@ EC_ORIG_INTERNAL
Internal.
#define EC_DATAGRAM_NAME_SIZE
Size of the datagram description string.
@ EC_DEVICE_MAIN
Main device.
#define EC_ERR(fmt, args...)
Convenience macro for printing EtherCAT-specific errors to syslog.
#define EC_WRITE_U32(DATA, VAL)
Write a 32-bit unsigned value to EtherCAT data.
#define EC_WRITE_U16(DATA, VAL)
Write a 16-bit unsigned value to EtherCAT data.
#define EC_WRITE_S16(DATA, VAL)
Write a 16-bit signed value to EtherCAT data.
EtherCAT master structure.
size_t mem_size
Datagram data memory size.
uint16_t working_counter
Working counter.
size_t data_size
Size of the data in data.
unsigned long jiffies_received
Jiffies, when the datagram was received.
ec_datagram_type_t type
Datagram type (APRD, BWR, etc.).
unsigned long jiffies_sent
Jiffies, when the datagram was sent.
struct list_head queue
Master datagram queue item, protected by user-supplied mutex.
uint8_t index
Index (set by master).
ec_datagram_state_t state
State.
ec_device_index_t device_index
Device via which the datagram shall be / was sent.
unsigned long stats_output_jiffies
Last statistics output.
uint8_t address[EC_ADDR_LEN]
Recipient address.
uint8_t * data
Datagram payload.
ec_origin_t data_origin
Origin of the data memory.
char name[EC_DATAGRAM_NAME_SIZE]
Description of the datagram.
unsigned int skip_count
Number of requeues when not yet received.