Neues Interface.
This commit is contained in:
parent
eb4d69d3a6
commit
1a2c2881f5
|
|
@ -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);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -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 *);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
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
|
||||
|
||||
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,107 +452,42 @@ 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
|
||||
|
||||
EtherCAT_domain_init(&master->domains[master->domain_count]);
|
||||
master->domains[master->domain_count].number = cur->domain;
|
||||
master->domain_count++;
|
||||
}
|
||||
}
|
||||
data[0] = cur->station_address & 0x00FF;
|
||||
data[1] = (cur->station_address & 0xFF00) >> 8;
|
||||
|
||||
// Calculate domain sizes and addresses
|
||||
EtherCAT_command_position_write(&cmd, cur->ring_position,
|
||||
0x0010, 2, data);
|
||||
|
||||
offset = 0;
|
||||
for (i = 0; i < master->domain_count; i++)
|
||||
{
|
||||
dom = master->domains + i;
|
||||
if (unlikely(EtherCAT_simple_send_receive(master, &cmd) < 0))
|
||||
return -1;
|
||||
|
||||
dom->logical_offset = offset;
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
if (unlikely(cmd.working_counter != 1)) {
|
||||
printk(KERN_ERR "EtherCAT: Slave %i did not repond"
|
||||
" while writing station address!\n", i);
|
||||
return -1;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
dom->data_size = size;
|
||||
memset(dom->data, 0x00, size);
|
||||
|
||||
printk(KERN_INFO "EtherCAT: Domain %i: Offset 0x%04X, %i Bytes of"
|
||||
" process data.\n", dom->number, dom->logical_offset, size);
|
||||
|
||||
// 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;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
offset += size;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -603,6 +495,83 @@ int EtherCAT_check_slaves(EtherCAT_master_t *master,
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
Registriert einen Slave beim Master.
|
||||
|
||||
@param master Der EtherCAT-Master
|
||||
|
||||
@return 0 bei Erfolg, sonst < 0
|
||||
*/
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
slave = master->bus_slaves + bus_index;
|
||||
|
||||
if (slave->process_data) {
|
||||
printk(KERN_ERR "EtherCAT: Slave %i is already registered!\n", bus_index);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// 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++;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
Liest Daten aus dem Slave-Information-Interface
|
||||
eines EtherCAT-Slaves.
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 *);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 *);
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue