Skip to content
Snippets Groups Projects
Commit 8c5d9567 authored by Florian Pose's avatar Florian Pose
Browse files

Neues Interface.

parent 72cffb9e
No related branches found
No related tags found
No related merge requests found
...@@ -24,28 +24,11 @@ ...@@ -24,28 +24,11 @@
void EtherCAT_domain_init(EtherCAT_domain_t *dom) void EtherCAT_domain_init(EtherCAT_domain_t *dom)
{ {
dom->number = 0; dom->number = 0;
dom->data = NULL;
dom->data_size = 0; dom->data_size = 0;
dom->logical_offset = 0; dom->logical_offset = 0;
dom->response_count = 0; dom->response_count = 0;
}
/*****************************************************************************/
/**
Destruktor eines Prozessdatenobjekts.
@param dom Zeiger auf die zu lschenden Prozessdaten memset(dom->data, 0x00, ECAT_FRAME_BUFFER_SIZE);
*/
void EtherCAT_domain_clear(EtherCAT_domain_t *dom)
{
if (dom->data) {
kfree(dom->data);
dom->data = NULL;
}
dom->data_size = 0;
} }
/*****************************************************************************/ /*****************************************************************************/
......
...@@ -29,8 +29,8 @@ typedef struct EtherCAT_domain ...@@ -29,8 +29,8 @@ typedef struct EtherCAT_domain
unsigned int number; /*<< Domnen-Identifikation */ unsigned int number; /*<< Domnen-Identifikation */
EtherCAT_command_t command; /**< Kommando zum Senden und Empfangen der EtherCAT_command_t command; /**< Kommando zum Senden und Empfangen der
Prozessdaten */ Prozessdaten */
unsigned char *data; /**< Zeiger auf Speicher mit Prozessdaten */ unsigned char data[ECAT_FRAME_BUFFER_SIZE]; /**< Prozessdaten-Array */
unsigned int data_size; /**< Gre des Prozessdatenspeichers */ unsigned int data_size; /**< Gre der Prozessdaten */
unsigned int logical_offset; /**< Logische Basisaddresse */ unsigned int logical_offset; /**< Logische Basisaddresse */
unsigned int response_count; /**< Anzahl antwortender Slaves */ unsigned int response_count; /**< Anzahl antwortender Slaves */
} }
...@@ -39,7 +39,6 @@ EtherCAT_domain_t; ...@@ -39,7 +39,6 @@ EtherCAT_domain_t;
/*****************************************************************************/ /*****************************************************************************/
void EtherCAT_domain_init(EtherCAT_domain_t *); void EtherCAT_domain_init(EtherCAT_domain_t *);
void EtherCAT_domain_clear(EtherCAT_domain_t *);
/*****************************************************************************/ /*****************************************************************************/
......
...@@ -27,6 +27,8 @@ ...@@ -27,6 +27,8 @@
void EtherCAT_master_init(EtherCAT_master_t *master) void EtherCAT_master_init(EtherCAT_master_t *master)
{ {
master->bus_slaves = NULL;
master->bus_slaves_count = 0;
master->dev = NULL; master->dev = NULL;
master->command_index = 0x00; master->command_index = 0x00;
master->tx_data_length = 0; master->tx_data_length = 0;
...@@ -51,11 +53,9 @@ void EtherCAT_master_init(EtherCAT_master_t *master) ...@@ -51,11 +53,9 @@ void EtherCAT_master_init(EtherCAT_master_t *master)
void EtherCAT_master_clear(EtherCAT_master_t *master) void EtherCAT_master_clear(EtherCAT_master_t *master)
{ {
unsigned int i; if (master->bus_slaves) {
kfree(master->bus_slaves);
// Remove domains master->bus_slaves = NULL;
for (i = 0; i < master->domain_count; i++) {
EtherCAT_domain_clear(master->domains + i);
} }
master->domain_count = 0; master->domain_count = 0;
...@@ -353,42 +353,19 @@ int EtherCAT_simple_receive(EtherCAT_master_t *master, ...@@ -353,42 +353,19 @@ int EtherCAT_simple_receive(EtherCAT_master_t *master,
/*****************************************************************************/ /*****************************************************************************/
/** /**
Überprüft die angeschlossenen Slaves. Durchsucht den Bus nach 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.
@param master Der EtherCAT-Master @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 @return 0 bei Erfolg, sonst < 0
*/ */
int EtherCAT_check_slaves(EtherCAT_master_t *master, int EtherCAT_scan_for_slaves(EtherCAT_master_t *master)
EtherCAT_slave_t *slaves,
unsigned int slave_count)
{ {
EtherCAT_command_t cmd; EtherCAT_command_t cmd;
EtherCAT_slave_t *cur; EtherCAT_slave_t *cur;
unsigned int i, j, found, size, offset; unsigned int i, j;
unsigned char data[2]; 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 // Determine number of slaves on bus
...@@ -397,44 +374,24 @@ int EtherCAT_check_slaves(EtherCAT_master_t *master, ...@@ -397,44 +374,24 @@ int EtherCAT_check_slaves(EtherCAT_master_t *master,
if (unlikely(EtherCAT_simple_send_receive(master, &cmd) < 0)) if (unlikely(EtherCAT_simple_send_receive(master, &cmd) < 0))
return -1; return -1;
if (unlikely(cmd.working_counter != slave_count)) { master->bus_slaves_count = cmd.working_counter;
printk(KERN_ERR "EtherCAT: Wrong number of slaves on bus: %i / %i\n", printk("EtherCAT: Found %i slaves on bus.\n", master->bus_slaves_count);
cmd.working_counter, slave_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; return -1;
} }
printk("EtherCAT: Found all %i slaves.\n", slave_count);
// For every slave in the list // 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]; cur = master->bus_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;
// Write station address EtherCAT_slave_init(cur);
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;
}
// Read base data // Read base data
...@@ -495,110 +452,122 @@ int EtherCAT_check_slaves(EtherCAT_master_t *master, ...@@ -495,110 +452,122 @@ int EtherCAT_check_slaves(EtherCAT_master_t *master,
// Search for identification in "database" // Search for identification in "database"
found = 0;
for (j = 0; j < slave_ident_count; j++) for (j = 0; j < slave_ident_count; j++)
{ {
if (unlikely(slave_idents[j].vendor_id == cur->vendor_id if (unlikely(slave_idents[j].vendor_id == cur->vendor_id
&& slave_idents[j].product_code == cur->product_code)) && slave_idents[j].product_code == cur->product_code))
{ {
found = 1; cur->desc = slave_idents[j].desc;
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;
}
break; break;
} }
} }
if (unlikely(!found)) { if (unlikely(!cur->desc)) {
printk(KERN_ERR "EtherCAT: Unknown slave device" printk(KERN_ERR "EtherCAT: Unknown slave device (vendor %X, code %X) at "
" (vendor %X, code %X) at position %i.\n", " position %i.\n", cur->vendor_id, cur->product_code, i);
cur->vendor_id, cur->product_code, i);
return -1; return -1;
} }
// Check, if process data domain already exists... // Set ring position
found = 0; cur->ring_position = -i;
for (j = 0; j < master->domain_count; j++) { cur->station_address = i + 1;
if (cur->domain == master->domains[j].number) {
found = 1;
}
}
// Create process data domain // Write station address
if (!found) {
if (master->domain_count + 1 >= ECAT_MAX_DOMAINS) { data[0] = cur->station_address & 0x00FF;
printk(KERN_ERR "EtherCAT: Too many domains!\n"); data[1] = (cur->station_address & 0xFF00) >> 8;
return -1;
} EtherCAT_command_position_write(&cmd, cur->ring_position,
0x0010, 2, data);
EtherCAT_domain_init(&master->domains[master->domain_count]); if (unlikely(EtherCAT_simple_send_receive(master, &cmd) < 0))
master->domains[master->domain_count].number = cur->domain; return -1;
master->domain_count++;
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 @param master Der EtherCAT-Master
size = 0;
for (j = 0; j < slave_count; j++) {
if (slaves[j].domain == dom->number) {
size += slaves[j].desc->process_data_size;
}
}
if (size > ECAT_FRAME_BUFFER_SIZE - 14) { @return 0 bei Erfolg, sonst < 0
printk(KERN_ERR "EtherCAT: Oversized domain %i: %i / %i Bytes!\n", */
dom->number, size, ECAT_FRAME_BUFFER_SIZE - 14);
return -1;
}
if (!(dom->data = (unsigned char *) kmalloc(sizeof(unsigned char) void *EtherCAT_register_slave(EtherCAT_master_t *master,
* size, GFP_KERNEL))) { unsigned int bus_index,
printk(KERN_ERR "EtherCAT: Could not allocate %i bytes of domain" const char *vendor_name,
" data.\n", size); const char *product_name,
return -1; unsigned int domain)
} {
EtherCAT_slave_t *slave;
EtherCAT_domain_t *dom;
unsigned int j;
dom->data_size = size; if (bus_index >= master->bus_slaves_count) {
memset(dom->data, 0x00, size); 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" slave = master->bus_slaves + bus_index;
" process data.\n", dom->number, dom->logical_offset, size);
// Set logical addresses and data pointers of domain slaves if (slave->process_data) {
size = 0; printk(KERN_ERR "EtherCAT: Slave %i is already registered!\n", bus_index);
for (j = 0; j < slave_count; j++) { return NULL;
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;
printk(KERN_INFO "EtherCAT: Slave %i: Logical Address 0x%04X, %i" if (strcmp(vendor_name, slave->desc->vendor_name) ||
" bytes of process data.\n", j, slaves[j].logical_address, strcmp(product_name, slave->desc->product_name)) {
slaves[j].desc->process_data_size); 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) ...@@ -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_open);
EXPORT_SYMBOL(EtherCAT_master_close); EXPORT_SYMBOL(EtherCAT_master_close);
EXPORT_SYMBOL(EtherCAT_check_slaves);
EXPORT_SYMBOL(EtherCAT_activate_slave); EXPORT_SYMBOL(EtherCAT_activate_slave);
EXPORT_SYMBOL(EtherCAT_deactivate_slave); EXPORT_SYMBOL(EtherCAT_deactivate_slave);
EXPORT_SYMBOL(EtherCAT_process_data_cycle); EXPORT_SYMBOL(EtherCAT_process_data_cycle);
......
...@@ -27,6 +27,8 @@ ...@@ -27,6 +27,8 @@
struct EtherCAT_master 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 */ EtherCAT_device_t *dev; /**< Zeiger auf das zugewiesene EtherCAT-Gerät */
unsigned char command_index; /**< Aktueller Kommando-Index */ unsigned char command_index; /**< Aktueller Kommando-Index */
unsigned char tx_data[ECAT_FRAME_BUFFER_SIZE]; /**< Statischer Speicher unsigned char tx_data[ECAT_FRAME_BUFFER_SIZE]; /**< Statischer Speicher
...@@ -47,6 +49,17 @@ struct EtherCAT_master ...@@ -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 // Master creation and deletion
void EtherCAT_master_init(EtherCAT_master_t *); void EtherCAT_master_init(EtherCAT_master_t *);
void EtherCAT_master_clear(EtherCAT_master_t *); void EtherCAT_master_clear(EtherCAT_master_t *);
...@@ -61,20 +74,14 @@ int EtherCAT_simple_send(EtherCAT_master_t *, EtherCAT_command_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 *); int EtherCAT_simple_receive(EtherCAT_master_t *, EtherCAT_command_t *);
// Slave management // Slave management
int EtherCAT_check_slaves(EtherCAT_master_t *, EtherCAT_slave_t *, int EtherCAT_scan_for_slaves(EtherCAT_master_t *);
unsigned int);
int EtherCAT_read_slave_information(EtherCAT_master_t *, unsigned short int, int EtherCAT_read_slave_information(EtherCAT_master_t *, unsigned short int,
unsigned short int, unsigned 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 *, int EtherCAT_state_change(EtherCAT_master_t *, EtherCAT_slave_t *,
unsigned char); unsigned char);
// Process data // Misc.
int EtherCAT_process_data_cycle(EtherCAT_master_t *, unsigned int,
unsigned int);
// Private functions
void output_debug_data(const EtherCAT_master_t *); void output_debug_data(const EtherCAT_master_t *);
void ecat_output_lost_frames(EtherCAT_master_t *); void ecat_output_lost_frames(EtherCAT_master_t *);
......
...@@ -24,6 +24,9 @@ ...@@ -24,6 +24,9 @@
#include "ec_module.h" #include "ec_module.h"
int __init ecat_init_module(void);
void __exit ecat_cleanup_module(void);
/*****************************************************************************/ /*****************************************************************************/
#define LIT(X) #X #define LIT(X) #X
...@@ -229,6 +232,11 @@ EtherCAT_master_t *EtherCAT_request(int index) ...@@ -229,6 +232,11 @@ EtherCAT_master_t *EtherCAT_request(int index)
return NULL; 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; ecat_masters_reserved[index] = 1;
printk(KERN_INFO "EtherCAT: Reserved master %i.\n", index); printk(KERN_INFO "EtherCAT: Reserved master %i.\n", index);
......
...@@ -26,9 +26,6 @@ ...@@ -26,9 +26,6 @@
/*****************************************************************************/ /*****************************************************************************/
int __init ecat_init_module(void);
void __exit ecat_cleanup_module(void);
// Registration of devices // Registration of devices
int EtherCAT_register_device(int, EtherCAT_device_t *); int EtherCAT_register_device(int, EtherCAT_device_t *);
void EtherCAT_unregister_device(int, EtherCAT_device_t *); void EtherCAT_unregister_device(int, EtherCAT_device_t *);
......
...@@ -48,21 +48,6 @@ void EtherCAT_slave_init(EtherCAT_slave_t *slave) ...@@ -48,21 +48,6 @@ void EtherCAT_slave_init(EtherCAT_slave_t *slave)
/*****************************************************************************/ /*****************************************************************************/
/**
EtherCAT-Slave-Destruktor.
Im Moment ohne Funktionalitt.
@param slave Zeiger auf den zu zerstrenden Slave
*/
void EtherCAT_slave_clear(EtherCAT_slave_t *slave)
{
// Nothing yet...
}
/*****************************************************************************/
/** /**
Liest einen bestimmten Kanal des Slaves als Integer-Wert. Liest einen bestimmten Kanal des Slaves als Integer-Wert.
......
...@@ -62,7 +62,6 @@ EtherCAT_slave_t; ...@@ -62,7 +62,6 @@ EtherCAT_slave_t;
// Slave construction and deletion // Slave construction and deletion
void EtherCAT_slave_init(EtherCAT_slave_t *); void EtherCAT_slave_init(EtherCAT_slave_t *);
void EtherCAT_slave_clear(EtherCAT_slave_t *);
int EtherCAT_read_value(EtherCAT_slave_t *, unsigned int); int EtherCAT_read_value(EtherCAT_slave_t *, unsigned int);
void EtherCAT_write_value(EtherCAT_slave_t *, unsigned int, int); void EtherCAT_write_value(EtherCAT_slave_t *, unsigned int, int);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment