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,
#define EC_WARN(fmt, args...)
Convenience macro for printing EtherCAT-specific warnings to syslog.
unsigned long jiffies_sent
Jiffies, when the datagram was sent.
Auto Increment Physical Read Multiple Write.
#define EC_ADDR_LEN
Size of the EtherCAT address field.
static const char * type_strings[]
Array of datagram type strings used in ec_datagram_type_string().
#define EC_DATAGRAM_NAME_SIZE
Size of the datagram description string.
Auto Increment Physical ReadWrite.
size_t data_size
Size of the data in data.
unsigned long stats_output_jiffies
Last statistics output.
ec_origin_t data_origin
Origin of the data memory.
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.
char name[EC_DATAGRAM_NAME_SIZE]
Description of the datagram.
uint16_t working_counter
Working counter.
#define EC_WRITE_S16(DATA, VAL)
Write a 16-bit signed value to EtherCAT data.
Sent (still in the queue).
Configured Address Physical Read.
void ec_datagram_output_stats(ec_datagram_t *datagram)
Outputs datagram statistics at most every second.
int ec_datagram_lwr(ec_datagram_t *datagram, uint32_t offset, size_t data_size)
Initializes an EtherCAT LWR 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.
ec_datagram_type_t type
Datagram type (APRD, BWR, etc.).
EtherCAT master structure.
Initial state of a new datagram.
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.
void ec_datagram_zero(ec_datagram_t *datagram)
Fills the datagram payload memory with zeros.
ec_datagram_state_t state
State.
#define EC_WRITE_U32(DATA, VAL)
Write a 32-bit unsigned value to EtherCAT data.
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.
void ec_datagram_print_wc_error(const ec_datagram_t *datagram)
Evaluates the working counter of a single-cast datagram.
#define EC_WRITE_U16(DATA, VAL)
Write a 16-bit unsigned value to EtherCAT data.
unsigned int skip_count
Number of requeues when not yet received.
Auto Increment Physical Read.
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.
void ec_datagram_unqueue(ec_datagram_t *datagram)
Unqueue 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.
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.
ec_device_index_t device_index
Device via which the datagram shall be / was sent.
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_lrd(ec_datagram_t *datagram, uint32_t offset, size_t data_size)
Initializes an EtherCAT LRD datagram.
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_prealloc(ec_datagram_t *datagram, size_t size)
Allocates internal payload memory.
Configured Address Physical Read Multiple Write.
void ec_datagram_print_state(const ec_datagram_t *datagram)
Prints the state of a datagram.
#define EC_ERR(fmt, args...)
Convenience macro for printing EtherCAT-specific errors to syslog.
int ec_datagram_brw(ec_datagram_t *datagram, uint16_t mem_address, size_t data_size)
Initializes an EtherCAT BRW datagram.
void ec_datagram_init(ec_datagram_t *datagram)
Constructor.
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.
const char * ec_datagram_type_string(const ec_datagram_t *datagram)
Returns a string describing the datagram type.
uint8_t * data
Datagram payload.
Configured Address Physical ReadWrite.
struct list_head queue
Master datagram queue item, protected by user-supplied mutex.
size_t mem_size
Datagram data memory size.
Error while sending/receiving (dequeued).
Auto Increment Physical Write.
uint8_t address[EC_ADDR_LEN]
Recipient address.
Configured Address Physical Write.
uint8_t index
Index (set by master).
int ec_datagram_lrw(ec_datagram_t *datagram, uint32_t offset, size_t data_size)
Initializes an EtherCAT LRW datagram.
unsigned long jiffies_received
Jiffies, when the datagram was received.
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.
int ec_datagram_bwr(ec_datagram_t *datagram, uint16_t mem_address, size_t data_size)
Initializes an EtherCAT BWR datagram.
void ec_datagram_clear(ec_datagram_t *datagram)
Destructor.