29 #include <linux/module.h> 40 #define DEBUG_REDUNDANCY 0 47 const unsigned int []);
49 #if EC_MAX_NUM_DEVICES > 1 66 domain->
index = index;
92 list_for_each_entry_safe(datagram_pair, next_pair,
132 " Added %u bytes, total %zu.\n",
148 uint32_t logical_offset,
151 const unsigned int used[]
159 "Failed to allocate domain datagram pair!\n");
166 kfree(datagram_pair);
174 "Adding datagram pair with expected WC %u.\n",
200 for (; first_fmmu != cur_fmmu;
201 first_fmmu = list_entry(first_fmmu->
list.next,
204 if (first_fmmu->
sc == cur_fmmu->
sc 205 && first_fmmu->
dir == cur_fmmu->
dir) {
227 uint32_t base_address
230 uint32_t datagram_offset;
231 size_t datagram_size;
232 unsigned int datagram_count;
243 (uint8_t *) kmalloc(domain->
data_size, GFP_KERNEL))) {
245 " internal memory for domain %u!\n",
262 datagram_first_fmmu =
266 list_for_each_entry(fmmu, &domain->
fmmu_configs, list) {
276 datagram_size, domain->
data + datagram_offset,
281 datagram_offset += datagram_size;
286 datagram_first_fmmu = fmmu;
292 datagram_used[fmmu->
dir]++;
303 datagram_size, domain->
data + datagram_offset,
311 " %zu byte, expected working counter %u.\n", domain->
index,
315 list_for_each_entry(datagram_pair, &domain->
datagram_pairs, list) {
319 " %zu byte, type %s.\n", datagram->
name,
334 unsigned int num = 0;
336 list_for_each_entry(fmmu, &domain->
fmmu_configs, list) {
356 list_for_each_entry(fmmu, &domain->
fmmu_configs, list) {
367 #if EC_MAX_NUM_DEVICES > 1 372 uint8_t *send_buffer,
378 uint8_t *sent = send_buffer + offset;
379 uint8_t *recv = datagram->
data + offset;
382 for (i = 0; i < size; i++) {
383 if (recv[i] != sent[i]) {
405 "domain = 0x%p, regs = 0x%p)\n", domain, regs);
407 for (reg = regs; reg->
index; reg++) {
436 "domain = 0x%p, mem = 0x%p)\n", domain, mem);
459 uint16_t wc_sum[EC_MAX_NUM_DEVICES] = {}, wc_total;
461 #if EC_MAX_NUM_DEVICES > 1 462 uint16_t datagram_pair_wc, redundant_wc;
463 unsigned int datagram_offset;
466 unsigned int redundancy;
468 unsigned int dev_idx;
470 unsigned int wc_change;
478 #if EC_MAX_NUM_DEVICES > 1 484 #if EC_MAX_NUM_DEVICES > 1 487 uint32_t logical_datagram_address =
489 size_t datagram_size = main_datagram->
data_size;
493 main_datagram->
name, logical_datagram_address);
497 list_for_each_entry_from(fmmu, &domain->
fmmu_configs, list) {
506 logical_datagram_address + datagram_size) {
516 "input fmmu log=%u size=%u offset=%u\n",
535 }
else if (
data_changed(pair->send_buffer, backup_datagram,
541 memcpy(main_datagram->
data + datagram_offset,
542 backup_datagram->
data + datagram_offset,
544 }
else if (datagram_pair_wc ==
549 "no change but complete\n");
554 datagram_pair_wc = 0;
557 "no change and incomplete\n");
562 #endif // EC_MAX_NUM_DEVICES > 1 565 #if EC_MAX_NUM_DEVICES > 1 569 redundant_wc += wc_sum[dev_idx];
572 redundancy = redundant_wc > 0;
577 "Domain %u: Redundant link in use!\n",
581 "Domain %u: Redundant link unused again.\n",
603 wc_total += wc_sum[dev_idx];
616 " changed to %u/%u", domain->
index,
620 " changes - now %u/%u", domain->
index,
624 #if EC_MAX_NUM_DEVICES > 1 626 printk(KERN_CONT
" (");
632 printk(KERN_CONT
"+");
635 printk(KERN_CONT
")");
638 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,
681 unsigned int dev_idx;
unsigned int working_counter
Value of the last working counter.
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.
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.
uint16_t index
PDO entry index.
#define ec_master_num_devices(MASTER)
Number of Ethernet devices.
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 ecrt_domain_state(const ec_domain_t *domain, ec_domain_state_t *state)
Reads the state of 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 *, const ec_datagram_t *, size_t, size_t)
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.
uint8_t * ecrt_domain_data(const ec_domain_t *domain)
Returns the domain's process data.
int ecrt_domain_queue(ec_domain_t *domain)
(Re-)queues all domain datagrams in the master's datagram queue.
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.
size_t ecrt_domain_size(const ec_domain_t *domain)
Returns the current size of the domain's process data.
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_domain_process(ec_domain_t *domain)
Determines the states of the domain's datagrams.
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.
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. ...
uint8_t address[EC_ADDR_LEN]
Recipient address.
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.
#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 *, uint32_t, size_t, uint8_t *, const unsigned int [])
Allocates a domain datagram pair and appends it to the list.
int shall_count(const ec_fmmu_config_t *, const ec_fmmu_config_t *)
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.