37 #include <linux/module.h> 48 #define DEBUG_REDUNDANCY 0 67 domain->
index = index;
93 list_for_each_entry_safe(datagram_pair, next_pair,
133 " Added %u bytes, total %zu.\n",
149 uint32_t logical_offset,
152 const unsigned int used[]
160 "Failed to allocate domain datagram pair!\n");
167 kfree(datagram_pair);
175 "Adding datagram pair with expected WC %u.\n",
201 for (; first_fmmu != cur_fmmu;
202 first_fmmu = list_entry(first_fmmu->
list.next,
205 if (first_fmmu->
sc == cur_fmmu->
sc 206 && first_fmmu->
dir == cur_fmmu->
dir) {
228 uint32_t base_address
231 uint32_t datagram_offset;
232 size_t datagram_size;
233 unsigned int datagram_count;
244 (uint8_t *) kmalloc(domain->
data_size, GFP_KERNEL))) {
246 " internal memory for domain %u!\n",
263 datagram_first_fmmu =
267 list_for_each_entry(fmmu, &domain->
fmmu_configs, list) {
277 datagram_size, domain->
data + datagram_offset,
282 datagram_offset += datagram_size;
287 datagram_first_fmmu = fmmu;
293 datagram_used[fmmu->
dir]++;
304 datagram_size, domain->
data + datagram_offset,
312 " %zu byte, expected working counter %u.\n", domain->
index,
316 list_for_each_entry(datagram_pair, &domain->
datagram_pairs, list) {
320 " %zu byte, type %s.\n", datagram->
name,
335 unsigned int num = 0;
337 list_for_each_entry(fmmu, &domain->
fmmu_configs, list) {
357 list_for_each_entry(fmmu, &domain->
fmmu_configs, list) {
368 #if EC_MAX_NUM_DEVICES > 1 373 uint8_t *send_buffer,
379 uint8_t *sent = send_buffer + offset;
380 uint8_t *recv = datagram->
data + offset;
383 for (i = 0; i < size; i++) {
384 if (recv[i] != sent[i]) {
406 "domain = 0x%p, regs = 0x%p)\n", domain, regs);
408 for (reg = regs; reg->
index; reg++) {
437 "domain = 0x%p, mem = 0x%p)\n", domain, mem);
460 uint16_t wc_sum[EC_MAX_NUM_DEVICES] = {}, wc_total;
462 #if EC_MAX_NUM_DEVICES > 1 463 uint16_t datagram_pair_wc, redundant_wc;
464 unsigned int datagram_offset;
467 unsigned int redundancy;
469 unsigned int dev_idx;
471 unsigned int wc_change;
479 #if EC_MAX_NUM_DEVICES > 1 485 #if EC_MAX_NUM_DEVICES > 1 488 uint32_t logical_datagram_address =
490 size_t datagram_size = main_datagram->
data_size;
494 main_datagram->
name, logical_datagram_address);
498 list_for_each_entry_from(fmmu, &domain->
fmmu_configs, list) {
507 logical_datagram_address + datagram_size) {
517 "input fmmu log=%u size=%u offset=%u\n",
536 }
else if (
data_changed(pair->send_buffer, backup_datagram,
542 memcpy(main_datagram->
data + datagram_offset,
543 backup_datagram->
data + datagram_offset,
545 }
else if (datagram_pair_wc ==
550 "no change but complete\n");
555 datagram_pair_wc = 0;
558 "no change and incomplete\n");
563 #endif // EC_MAX_NUM_DEVICES > 1 566 #if EC_MAX_NUM_DEVICES > 1 570 redundant_wc += wc_sum[dev_idx];
573 redundancy = redundant_wc > 0;
578 "Domain %u: Redundant link in use!\n",
582 "Domain %u: Redundant link unused again.\n",
604 wc_total += wc_sum[dev_idx];
617 " changed to %u/%u", domain->
index,
621 " changes - now %u/%u", domain->
index,
625 #if EC_MAX_NUM_DEVICES > 1 627 printk(KERN_CONT
" (");
633 printk(KERN_CONT
"+");
636 printk(KERN_CONT
")");
639 printk(KERN_CONT
".\n");
653 list_for_each_entry(datagram_pair, &domain->
datagram_pairs, list) {
655 #if EC_MAX_NUM_DEVICES > 1 657 memcpy(datagram_pair->send_buffer,
680 unsigned int dev_idx;
unsigned int working_counter
Value of the last working counter.
size_t ecrt_domain_size(const ec_domain_t *domain)
Returns the current size of the domain's process data.
const ec_slave_config_t * sc
EtherCAT slave config.
uint8_t subindex
PDO entry subindex.
uint16_t position
Slave position.
size_t data_size
Size of the data in data.
size_t data_size
Size of the process data.
unsigned int expected_working_counter
Expectord working conter.
unsigned int redundancy_active
Redundant link is in use.
uint16_t index
PDO entry index.
#define ec_master_num_devices(MASTER)
Number of Ethernet devices.
int ecrt_domain_reg_pdo_entry_list(ec_domain_t *domain, const ec_pdo_entry_reg_t *regs)
Registers a bunch of PDO entries for a domain.
unsigned int data_size
Covered PDO size.
char name[EC_DATAGRAM_NAME_SIZE]
Description of the datagram.
ec_wc_state_t wc_state
Working counter interpretation.
int data_changed(uint8_t *send_buffer, const ec_datagram_t *datagram, size_t offset, size_t size)
Process received data.
void ecrt_domain_external_memory(ec_domain_t *domain, uint8_t *mem)
Provide external memory to store the domain's process data.
void ec_domain_clear_data(ec_domain_t *)
Frees internally allocated memory.
Global definitions and macros.
Some of the registered process data were exchanged.
EtherCAT master structure.
uint8_t * data
Memory for the process data.
uint16_t alias
Slave alias address.
#define EC_MASTER_DBG(master, level, fmt, args...)
Convenience macro for printing master-specific debug messages to syslog.
struct semaphore master_sem
Master semaphore.
uint32_t logical_start_address
Logical start address.
struct list_head list
List node used by domain.
unsigned int working_counter_changes
Working counter changes since last notification.
const ec_domain_t * domain
Domain.
uint32_t vendor_id
Slave vendor ID.
unsigned int * bit_position
Pointer to a variable to store a bit position (0-7) within the offset.
void ec_domain_clear(ec_domain_t *domain)
Domain destructor.
int ec_domain_finish(ec_domain_t *domain, uint32_t base_address)
Finishes a domain.
unsigned int debug_level
Master debug level.
uint16_t ec_datagram_pair_process(ec_datagram_pair_t *pair, uint16_t wc_sum[])
Process received data.
ec_device_index_t
Master devices.
void ec_datagram_pair_clear(ec_datagram_pair_t *pair)
Datagram pair destructor.
unsigned int index
Index (just a number).
#define EC_READ_U32(DATA)
Read a 32-bit unsigned value from EtherCAT data.
struct list_head fmmu_configs
FMMU configurations contained.
#define EC_MASTER_WARN(master, fmt, args...)
Convenience macro for printing master-specific warnings to syslog.
unsigned int ec_domain_fmmu_count(const ec_domain_t *domain)
Get the number of FMMU configurations of the domain.
#define EC_MASTER_ERR(master, fmt, args...)
Convenience macro for printing master-specific errors to syslog.
void ec_master_queue_datagram(ec_master_t *master, ec_datagram_t *datagram)
Places a datagram in the datagram queue.
Values read by the master.
ec_origin_t data_origin
Origin of the data memory.
void ec_print_data(const uint8_t *, size_t)
Outputs frame contents for debugging purposes.
uint16_t working_counter[EC_MAX_NUM_DEVICES]
Last working counter values.
uint32_t logical_base_address
Logical offset address of the process data.
uint16_t expected_working_counter
Expected working counter.
unsigned int redundancy_active
Non-zero, if redundancy is in use.
int ecrt_slave_config_reg_pdo_entry(ec_slave_config_t *sc, uint16_t index, uint8_t subindex, ec_domain_t *domain, unsigned int *bit_position)
Registers a PDO entry for process data exchange in a domain.
int ec_datagram_pair_init(ec_datagram_pair_t *pair, ec_domain_t *domain, uint32_t logical_offset, uint8_t *data, size_t data_size, const unsigned int used[])
Datagram pair constructor.
void ec_domain_add_fmmu_config(ec_domain_t *domain, ec_fmmu_config_t *fmmu)
Adds an FMMU configuration to the domain.
struct list_head list
List header.
uint8_t * ecrt_domain_data(ec_domain_t *domain)
Returns the domain's process data.
List record type for PDO entry mass-registration.
EtherCAT domain structure.
No registered process data were exchanged.
All registered process data were exchanged.
EtherCAT datagram pair structure.
const char * ec_datagram_type_string(const ec_datagram_t *datagram)
Returns a string describing the datagram type.
uint8_t * data
Datagram payload.
EtherCAT slave configuration.
ec_datagram_t datagrams[EC_MAX_NUM_DEVICES]
Datagrams.
EtherCAT slave configuration structure.
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.
unsigned int * offset
Pointer to a variable to store the PDO entry's (byte-)offset in the process data. ...
void ecrt_domain_state(const ec_domain_t *domain, ec_domain_state_t *state)
Reads the state of a domain.
uint8_t address[EC_ADDR_LEN]
Recipient address.
void ecrt_domain_process(ec_domain_t *domain)
Determines the states of the domain's datagrams.
void ec_domain_init(ec_domain_t *domain, ec_master_t *master, unsigned int index)
Domain constructor.
ec_direction_t dir
FMMU direction.
Values written by the master.
struct list_head datagram_pairs
Datagrams pairs (main/backup) for process data exchange.
void ecrt_domain_queue(ec_domain_t *domain)
(Re-)queues all domain datagrams in the master's datagram queue.
#define EC_MASTER_INFO(master, fmt, args...)
Convenience macro for printing master-specific information to syslog.
uint32_t product_code
Slave product code.
unsigned long notify_jiffies
Time of last notification.
int ec_domain_add_datagram_pair(ec_domain_t *domain, uint32_t logical_offset, size_t data_size, uint8_t *data, const unsigned int used[])
Allocates a domain datagram pair and appends it to the list.
int shall_count(const ec_fmmu_config_t *cur_fmmu, const ec_fmmu_config_t *first_fmmu)
Domain finish helper function.
ec_master_t * master
EtherCAT master owning the domain.
#define EC_MAX_DATA_SIZE
Resulting maximum data size of a single datagram in a frame.
const ec_fmmu_config_t * ec_domain_find_fmmu(const ec_domain_t *domain, unsigned int pos)
Get a certain FMMU configuration via its position in the list.