From 8c5d9567770548cf5ce1b6a8dddeb6ea19d1f8e4 Mon Sep 17 00:00:00 2001 From: Florian Pose <fp@igh-essen.com> Date: Fri, 13 Jan 2006 15:39:38 +0000 Subject: [PATCH] Neues Interface. --- drivers/ec_domain.c | 19 +--- drivers/ec_domain.h | 5 +- drivers/ec_master.c | 246 +++++++++++++++++++------------------------- drivers/ec_master.h | 23 +++-- drivers/ec_module.c | 8 ++ drivers/ec_module.h | 3 - drivers/ec_slave.c | 15 --- drivers/ec_slave.h | 1 - 8 files changed, 132 insertions(+), 188 deletions(-) diff --git a/drivers/ec_domain.c b/drivers/ec_domain.c index 35e4c54a..13d52c73 100644 --- a/drivers/ec_domain.c +++ b/drivers/ec_domain.c @@ -24,28 +24,11 @@ void EtherCAT_domain_init(EtherCAT_domain_t *dom) { dom->number = 0; - dom->data = NULL; dom->data_size = 0; dom->logical_offset = 0; dom->response_count = 0; -} - -/*****************************************************************************/ - -/** - Destruktor eines Prozessdatenobjekts. - @param dom Zeiger auf die zu löschenden Prozessdaten -*/ - -void EtherCAT_domain_clear(EtherCAT_domain_t *dom) -{ - if (dom->data) { - kfree(dom->data); - dom->data = NULL; - } - - dom->data_size = 0; + memset(dom->data, 0x00, ECAT_FRAME_BUFFER_SIZE); } /*****************************************************************************/ diff --git a/drivers/ec_domain.h b/drivers/ec_domain.h index 3bff745f..d89206ab 100644 --- a/drivers/ec_domain.h +++ b/drivers/ec_domain.h @@ -29,8 +29,8 @@ typedef struct EtherCAT_domain unsigned int number; /*<< Domänen-Identifikation */ EtherCAT_command_t command; /**< Kommando zum Senden und Empfangen der Prozessdaten */ - unsigned char *data; /**< Zeiger auf Speicher mit Prozessdaten */ - unsigned int data_size; /**< Größe des Prozessdatenspeichers */ + unsigned char data[ECAT_FRAME_BUFFER_SIZE]; /**< Prozessdaten-Array */ + unsigned int data_size; /**< Größe der Prozessdaten */ unsigned int logical_offset; /**< Logische Basisaddresse */ unsigned int response_count; /**< Anzahl antwortender Slaves */ } @@ -39,7 +39,6 @@ EtherCAT_domain_t; /*****************************************************************************/ void EtherCAT_domain_init(EtherCAT_domain_t *); -void EtherCAT_domain_clear(EtherCAT_domain_t *); /*****************************************************************************/ diff --git a/drivers/ec_master.c b/drivers/ec_master.c index db0088f2..d6ce83f1 100644 --- a/drivers/ec_master.c +++ b/drivers/ec_master.c @@ -27,6 +27,8 @@ void EtherCAT_master_init(EtherCAT_master_t *master) { + master->bus_slaves = NULL; + master->bus_slaves_count = 0; master->dev = NULL; master->command_index = 0x00; master->tx_data_length = 0; @@ -51,11 +53,9 @@ void EtherCAT_master_init(EtherCAT_master_t *master) void EtherCAT_master_clear(EtherCAT_master_t *master) { - unsigned int i; - - // Remove domains - for (i = 0; i < master->domain_count; i++) { - EtherCAT_domain_clear(master->domains + i); + if (master->bus_slaves) { + kfree(master->bus_slaves); + master->bus_slaves = NULL; } master->domain_count = 0; @@ -353,42 +353,19 @@ int EtherCAT_simple_receive(EtherCAT_master_t *master, /*****************************************************************************/ /** - Überprüft die angeschlossenen Slaves. - - Vergleicht die an den Bus angeschlossenen Slaves mit - den im statischen-Slave-Array vorgegebenen Konfigurationen. - Stimmen Anzahl oder Typen nicht überein, gibt diese - Methode einen Fehler aus. + Durchsucht den Bus nach Slaves. @param master Der EtherCAT-Master - @param slaves Zeiger auf ein statisches Slave-Array - @param slave_count Anzahl der Slaves im Array @return 0 bei Erfolg, sonst < 0 */ -int EtherCAT_check_slaves(EtherCAT_master_t *master, - EtherCAT_slave_t *slaves, - unsigned int slave_count) +int EtherCAT_scan_for_slaves(EtherCAT_master_t *master) { EtherCAT_command_t cmd; EtherCAT_slave_t *cur; - unsigned int i, j, found, size, offset; + unsigned int i, j; unsigned char data[2]; - EtherCAT_domain_t *dom; - - // Clear domains - for (i = 0; i < master->domain_count; i++) { - printk(KERN_DEBUG "EtherCAT: Clearing domain %i!\n", - master->domains[i].number); - EtherCAT_domain_clear(master->domains + i); - } - master->domain_count = 0; - - if (unlikely(!slave_count)) { - printk(KERN_ERR "EtherCAT: No slaves in list!\n"); - return -1; - } // Determine number of slaves on bus @@ -397,44 +374,24 @@ int EtherCAT_check_slaves(EtherCAT_master_t *master, if (unlikely(EtherCAT_simple_send_receive(master, &cmd) < 0)) return -1; - if (unlikely(cmd.working_counter != slave_count)) { - printk(KERN_ERR "EtherCAT: Wrong number of slaves on bus: %i / %i\n", - cmd.working_counter, slave_count); + master->bus_slaves_count = cmd.working_counter; + printk("EtherCAT: Found %i slaves on bus.\n", master->bus_slaves_count); + + if (!master->bus_slaves_count) return 0; + + if (!(master->bus_slaves = + (EtherCAT_slave_t *) kmalloc(master->bus_slaves_count * + sizeof(EtherCAT_slave_t), GFP_KERNEL))) { + printk(KERN_ERR "EtherCAT: Could not allocate memory for bus slaves!\n"); return -1; } - printk("EtherCAT: Found all %i slaves.\n", slave_count); - // For every slave in the list - for (i = 0; i < slave_count; i++) + for (i = 0; i < master->bus_slaves_count; i++) { - cur = &slaves[i]; - - if (unlikely(!cur->desc)) { - printk(KERN_ERR "EtherCAT: Slave %i has no description.\n", i); - return -1; - } - - // Set ring position - cur->ring_position = -i; - cur->station_address = i + 1; + cur = master->bus_slaves + i; - // Write station address - - data[0] = cur->station_address & 0x00FF; - data[1] = (cur->station_address & 0xFF00) >> 8; - - EtherCAT_command_position_write(&cmd, cur->ring_position, - 0x0010, 2, data); - - if (unlikely(EtherCAT_simple_send_receive(master, &cmd) < 0)) - return -1; - - if (unlikely(cmd.working_counter != 1)) { - printk(KERN_ERR "EtherCAT: Slave %i did not repond" - " while writing station address!\n", i); - return -1; - } + EtherCAT_slave_init(cur); // Read base data @@ -495,110 +452,122 @@ int EtherCAT_check_slaves(EtherCAT_master_t *master, // Search for identification in "database" - found = 0; - for (j = 0; j < slave_ident_count; j++) { if (unlikely(slave_idents[j].vendor_id == cur->vendor_id && slave_idents[j].product_code == cur->product_code)) { - found = 1; - - if (unlikely(cur->desc != slave_idents[j].desc)) { - printk(KERN_ERR "EtherCAT: Unexpected slave device" - " \"%s %s\" at position %i. Expected: \"%s %s\"\n", - slave_idents[j].desc->vendor_name, - slave_idents[j].desc->product_name, i, - cur->desc->vendor_name, cur->desc->product_name); - return -1; - } - + cur->desc = slave_idents[j].desc; break; } } - if (unlikely(!found)) { - printk(KERN_ERR "EtherCAT: Unknown slave device" - " (vendor %X, code %X) at position %i.\n", - cur->vendor_id, cur->product_code, i); + if (unlikely(!cur->desc)) { + printk(KERN_ERR "EtherCAT: Unknown slave device (vendor %X, code %X) at " + " position %i.\n", cur->vendor_id, cur->product_code, i); return -1; } - // Check, if process data domain already exists... - found = 0; - for (j = 0; j < master->domain_count; j++) { - if (cur->domain == master->domains[j].number) { - found = 1; - } - } + // Set ring position + cur->ring_position = -i; + cur->station_address = i + 1; - // Create process data domain - if (!found) { - if (master->domain_count + 1 >= ECAT_MAX_DOMAINS) { - printk(KERN_ERR "EtherCAT: Too many domains!\n"); - return -1; - } + // Write station address + + data[0] = cur->station_address & 0x00FF; + data[1] = (cur->station_address & 0xFF00) >> 8; + + EtherCAT_command_position_write(&cmd, cur->ring_position, + 0x0010, 2, data); - EtherCAT_domain_init(&master->domains[master->domain_count]); - master->domains[master->domain_count].number = cur->domain; - master->domain_count++; + if (unlikely(EtherCAT_simple_send_receive(master, &cmd) < 0)) + return -1; + + if (unlikely(cmd.working_counter != 1)) { + printk(KERN_ERR "EtherCAT: Slave %i did not repond" + " while writing station address!\n", i); + return -1; } } - // Calculate domain sizes and addresses + return 0; +} - offset = 0; - for (i = 0; i < master->domain_count; i++) - { - dom = master->domains + i; +/*****************************************************************************/ - dom->logical_offset = offset; +/** + Registriert einen Slave beim Master. - // Calculate size of the domain - size = 0; - for (j = 0; j < slave_count; j++) { - if (slaves[j].domain == dom->number) { - size += slaves[j].desc->process_data_size; - } - } + @param master Der EtherCAT-Master - if (size > ECAT_FRAME_BUFFER_SIZE - 14) { - printk(KERN_ERR "EtherCAT: Oversized domain %i: %i / %i Bytes!\n", - dom->number, size, ECAT_FRAME_BUFFER_SIZE - 14); - return -1; - } + @return 0 bei Erfolg, sonst < 0 +*/ - if (!(dom->data = (unsigned char *) kmalloc(sizeof(unsigned char) - * size, GFP_KERNEL))) { - printk(KERN_ERR "EtherCAT: Could not allocate %i bytes of domain" - " data.\n", size); - return -1; - } +void *EtherCAT_register_slave(EtherCAT_master_t *master, + unsigned int bus_index, + const char *vendor_name, + const char *product_name, + unsigned int domain) +{ + EtherCAT_slave_t *slave; + EtherCAT_domain_t *dom; + unsigned int j; - dom->data_size = size; - memset(dom->data, 0x00, size); + if (bus_index >= master->bus_slaves_count) { + printk(KERN_ERR "EtherCAT: Illegal bus index! (%i / %i)\n", bus_index, + master->bus_slaves_count); + return NULL; + } - printk(KERN_INFO "EtherCAT: Domain %i: Offset 0x%04X, %i Bytes of" - " process data.\n", dom->number, dom->logical_offset, size); + slave = master->bus_slaves + bus_index; - // Set logical addresses and data pointers of domain slaves - size = 0; - for (j = 0; j < slave_count; j++) { - if (slaves[j].domain == dom->number) { - slaves[j].process_data = dom->data + size; - slaves[j].logical_address = dom->logical_offset + size; - size += slaves[j].desc->process_data_size; + if (slave->process_data) { + printk(KERN_ERR "EtherCAT: Slave %i is already registered!\n", bus_index); + return NULL; + } - printk(KERN_INFO "EtherCAT: Slave %i: Logical Address 0x%04X, %i" - " bytes of process data.\n", j, slaves[j].logical_address, - slaves[j].desc->process_data_size); - } + if (strcmp(vendor_name, slave->desc->vendor_name) || + strcmp(product_name, slave->desc->product_name)) { + printk(KERN_ERR "Invalid Slave Type! Requested: \"%s %s\", present: \"%s" + "%s\".\n", vendor_name, product_name, slave->desc->vendor_name, + slave->desc->product_name); + return NULL; + } + + // Check, if process data domain already exists... + dom = NULL; + for (j = 0; j < master->domain_count; j++) { + if (domain == master->domains[j].number) { + dom = master->domains + j; } + } - offset += size; + // Create process data domain + if (!dom) { + if (master->domain_count > ECAT_MAX_DOMAINS - 1) { + printk(KERN_ERR "EtherCAT: Too many domains!\n"); + return NULL; + } + + dom = master->domains + master->domain_count; + EtherCAT_domain_init(dom); + dom->number = domain; + dom->logical_offset = master->domain_count * ECAT_FRAME_BUFFER_SIZE; + master->domain_count++; } - return 0; + if (dom->data_size + slave->desc->process_data_size + > ECAT_FRAME_BUFFER_SIZE - 14) { + printk(KERN_ERR "EtherCAT: Oversized domain %i: %i / %i Bytes!\n", + dom->number, dom->data_size + slave->desc->process_data_size, + ECAT_FRAME_BUFFER_SIZE - 14); + return NULL; + } + + slave->process_data = dom->data + dom->data_size; + dom->data_size += slave->desc->process_data_size; + + return slave->process_data; } /*****************************************************************************/ @@ -1142,11 +1111,8 @@ void ecat_output_lost_frames(EtherCAT_master_t *master) /*****************************************************************************/ -EXPORT_SYMBOL(EtherCAT_master_init); -EXPORT_SYMBOL(EtherCAT_master_clear); EXPORT_SYMBOL(EtherCAT_master_open); EXPORT_SYMBOL(EtherCAT_master_close); -EXPORT_SYMBOL(EtherCAT_check_slaves); EXPORT_SYMBOL(EtherCAT_activate_slave); EXPORT_SYMBOL(EtherCAT_deactivate_slave); EXPORT_SYMBOL(EtherCAT_process_data_cycle); diff --git a/drivers/ec_master.h b/drivers/ec_master.h index 3b51d061..e88647a1 100644 --- a/drivers/ec_master.h +++ b/drivers/ec_master.h @@ -27,6 +27,8 @@ struct EtherCAT_master { + EtherCAT_slave_t *bus_slaves; /**< Array von Slaves auf dem Bus */ + unsigned int bus_slaves_count; /**< Anzahl Slaves auf dem Bus */ EtherCAT_device_t *dev; /**< Zeiger auf das zugewiesene EtherCAT-Gerät */ unsigned char command_index; /**< Aktueller Kommando-Index */ unsigned char tx_data[ECAT_FRAME_BUFFER_SIZE]; /**< Statischer Speicher @@ -47,6 +49,17 @@ struct EtherCAT_master /*****************************************************************************/ +// Public methods + +void *EtherCAT_register_slave(EtherCAT_master_t *, unsigned int, + const char *, const char *, unsigned int); +int EtherCAT_activate_slave(EtherCAT_master_t *, EtherCAT_slave_t *); +int EtherCAT_deactivate_slave(EtherCAT_master_t *, EtherCAT_slave_t *); +int EtherCAT_process_data_cycle(EtherCAT_master_t *, unsigned int, + unsigned int); + +// Private Methods + // Master creation and deletion void EtherCAT_master_init(EtherCAT_master_t *); void EtherCAT_master_clear(EtherCAT_master_t *); @@ -61,20 +74,14 @@ int EtherCAT_simple_send(EtherCAT_master_t *, EtherCAT_command_t *); int EtherCAT_simple_receive(EtherCAT_master_t *, EtherCAT_command_t *); // Slave management -int EtherCAT_check_slaves(EtherCAT_master_t *, EtherCAT_slave_t *, - unsigned int); +int EtherCAT_scan_for_slaves(EtherCAT_master_t *); int EtherCAT_read_slave_information(EtherCAT_master_t *, unsigned short int, unsigned short int, unsigned int *); -int EtherCAT_activate_slave(EtherCAT_master_t *, EtherCAT_slave_t *); -int EtherCAT_deactivate_slave(EtherCAT_master_t *, EtherCAT_slave_t *); int EtherCAT_state_change(EtherCAT_master_t *, EtherCAT_slave_t *, unsigned char); -// Process data -int EtherCAT_process_data_cycle(EtherCAT_master_t *, unsigned int, - unsigned int); +// Misc. -// Private functions void output_debug_data(const EtherCAT_master_t *); void ecat_output_lost_frames(EtherCAT_master_t *); diff --git a/drivers/ec_module.c b/drivers/ec_module.c index aa8e89dd..bd8adf8f 100644 --- a/drivers/ec_module.c +++ b/drivers/ec_module.c @@ -24,6 +24,9 @@ #include "ec_module.h" +int __init ecat_init_module(void); +void __exit ecat_cleanup_module(void); + /*****************************************************************************/ #define LIT(X) #X @@ -229,6 +232,11 @@ EtherCAT_master_t *EtherCAT_request(int index) return NULL; } + if (EtherCAT_scan_for_slaves(&ecat_masters[index]) != 0) { + printk(KERN_ERR "EtherCAT: Could not scan for slaves!\n"); + return NULL; + } + ecat_masters_reserved[index] = 1; printk(KERN_INFO "EtherCAT: Reserved master %i.\n", index); diff --git a/drivers/ec_module.h b/drivers/ec_module.h index a3cce95e..9ebe60f3 100644 --- a/drivers/ec_module.h +++ b/drivers/ec_module.h @@ -26,9 +26,6 @@ /*****************************************************************************/ -int __init ecat_init_module(void); -void __exit ecat_cleanup_module(void); - // Registration of devices int EtherCAT_register_device(int, EtherCAT_device_t *); void EtherCAT_unregister_device(int, EtherCAT_device_t *); diff --git a/drivers/ec_slave.c b/drivers/ec_slave.c index d8309cd7..1d7306f1 100644 --- a/drivers/ec_slave.c +++ b/drivers/ec_slave.c @@ -48,21 +48,6 @@ void EtherCAT_slave_init(EtherCAT_slave_t *slave) /*****************************************************************************/ -/** - EtherCAT-Slave-Destruktor. - - Im Moment ohne Funktionalität. - - @param slave Zeiger auf den zu zerstörenden Slave -*/ - -void EtherCAT_slave_clear(EtherCAT_slave_t *slave) -{ - // Nothing yet... -} - -/*****************************************************************************/ - /** Liest einen bestimmten Kanal des Slaves als Integer-Wert. diff --git a/drivers/ec_slave.h b/drivers/ec_slave.h index e03e490f..df9c7aed 100644 --- a/drivers/ec_slave.h +++ b/drivers/ec_slave.h @@ -62,7 +62,6 @@ EtherCAT_slave_t; // Slave construction and deletion void EtherCAT_slave_init(EtherCAT_slave_t *); -void EtherCAT_slave_clear(EtherCAT_slave_t *); int EtherCAT_read_value(EtherCAT_slave_t *, unsigned int); void EtherCAT_write_value(EtherCAT_slave_t *, unsigned int, int); -- GitLab