EtherCAT-Master in eigenes Modul ausgelagert.

This commit is contained in:
Florian Pose 2005-12-02 15:35:21 +00:00
parent 6385143965
commit 4286780f31
8 changed files with 369 additions and 204 deletions

View File

@ -109,7 +109,7 @@
*/
#define DRV_NAME "8139too-ecat"
#define DRV_NAME "8139too_ecat"
#define DRV_VERSION "0.9.27"
@ -135,6 +135,8 @@
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
#include "ec_device.h"
#include "ec_master.h"
#include "ec_module.h"
/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
@ -192,12 +194,15 @@ static int debug = -1;
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
// Device index for EtherCAT device selection
static int ec_device_index = -1;
// Uncomment for debugging
//#define ECAT_DEBUG
EtherCAT_device_t rtl_ecat_dev;
// Device index for EtherCAT device selection
static int ec_device_index = -1;
static int ec_device_master_index = 0;
static EtherCAT_device_t rtl_ecat_dev;
static EtherCAT_master_t *rtl_ecat_master = NULL;
/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
@ -653,8 +658,10 @@ MODULE_PARM_DESC (full_duplex, "8139too: Force full duplex for board(s) (1)");
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
MODULE_PARM(ec_device_index, "i");
module_param(ec_device_index, int, -1);
module_param(ec_device_master_index, int, 0);
MODULE_PARM_DESC(ec_device_index, "Index of the device reserved for EtherCAT.");
MODULE_PARM_DESC(ec_device_master_index, "Index of the EtherCAT master to register the device.");
/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
@ -1016,7 +1023,7 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
if (EtherCAT_device_assign(&rtl_ecat_dev, dev) < 0)
goto err_out;
strcpy(dev->name,"ECAT"); //device name überschreiben
strcpy(dev->name,"ecat0"); //device name überschreiben
}
/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
@ -2955,28 +2962,73 @@ static int __init rtl8139_init_module (void)
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
printk(KERN_INFO "Initializing RTL8139-EtherCAT module.\n");
EtherCAT_device_init(&rtl_ecat_dev);
rtl_ecat_dev.isr = rtl8139_interrupt;
/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
if (pci_module_init(&rtl8139_pci_driver) < 0)
{
printk(KERN_ERR "Could not init PCI module.\n");
return -1;
}
return pci_module_init (&rtl8139_pci_driver);
printk(KERN_INFO "EtherCAT device index is %i.\n", ec_device_index);
if (rtl_ecat_dev.dev)
{
if ((rtl_ecat_master = EtherCAT_master(ec_device_master_index)) == NULL)
{
printk(KERN_ERR "Could not get EtherCAT master %i.\n",
ec_device_master_index);
goto out_module;
}
printk(KERN_INFO "Registering EtherCAT device...\n");
if (EtherCAT_register_device(rtl_ecat_master, &rtl_ecat_dev) < 0)
{
printk(KERN_ERR "Could not register device.\n");
goto out_module;
}
printk(KERN_INFO "EtherCAT device registered and opened.\n");
}
else
{
printk(KERN_WARNING "NO EtherCAT device registered!\n");
}
return 0;
out_module:
pci_unregister_driver(&rtl8139_pci_driver);
return -1;
/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
}
static void __exit rtl8139_cleanup_module (void)
{
pci_unregister_driver (&rtl8139_pci_driver);
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
printk(KERN_INFO "Cleaning up RTL8139-EtherCAT module...\n");
if (rtl_ecat_master && rtl_ecat_dev.dev)
{
printk(KERN_INFO "Unregistering RTL8139-EtherCAT device...\n");
EtherCAT_unregister_device(rtl_ecat_master, &rtl_ecat_dev);
}
pci_unregister_driver(&rtl8139_pci_driver);
EtherCAT_device_clear(&rtl_ecat_dev);
printk(KERN_INFO "RTL8139-EtherCAT module cleaned up.\n");
/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
}
module_init(rtl8139_init_module);
module_exit(rtl8139_cleanup_module);
EXPORT_SYMBOL(rtl_ecat_dev);

View File

@ -13,10 +13,12 @@ ifneq ($(KERNELRELEASE),)
#----------------------------------------------------------------
# Kbuild-Abschnitt
obj-m := 8139too-ecat.o
obj-m := 8139too-ecat.o ecat-master.o
8139too-ecat-objs := 8139too.o ec_device.o ec_master.o \
ec_slave.o ec_command.o ec_types.o
8139too-ecat-objs := 8139too.o
ecat-master-objs := ec_module.o ec_master.o ec_device.o \
ec_slave.o ec_command.o ec_types.o
#----------------------------------------------------------------
@ -28,7 +30,7 @@ else
CONFIG_FILE = ../ethercat.conf
PWD = $(shell pwd)
include $(CONFIG_FILE) # Für KERNELDIR
include $(CONFIG_FILE)
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules

View File

@ -144,7 +144,7 @@ int EtherCAT_device_open(EtherCAT_device_t *ecd)
if (!ecd->dev)
{
printk(KERN_ERR "EtherCAT: No device to open!\n");
printk(KERN_ERR "EtherCAT: No net_device to open!\n");
return -1;
}
@ -174,13 +174,10 @@ int EtherCAT_device_close(EtherCAT_device_t *ecd)
return -1;
}
printk("EtherCAT: txcnt: %u, rxcnt: %u\n",
printk("EtherCAT: Stopping device (txcnt: %u, rxcnt: %u)\n",
(unsigned int) ecd->tx_intr_cnt,
(unsigned int) ecd->rx_intr_cnt);
printk("EtherCAT: Stopping device at 0x%X\n",
(unsigned int) ecd->dev);
return ecd->dev->stop(ecd->dev);
}
@ -329,9 +326,10 @@ void EtherCAT_device_debug(EtherCAT_device_t *ecd)
/***************************************************************/
EXPORT_SYMBOL(EtherCAT_device_init);
EXPORT_SYMBOL(EtherCAT_device_clear);
EXPORT_SYMBOL(EtherCAT_device_assign);
EXPORT_SYMBOL(EtherCAT_device_open);
EXPORT_SYMBOL(EtherCAT_device_close);
EXPORT_SYMBOL(EtherCAT_device_clear);
EXPORT_SYMBOL(EtherCAT_device_debug);
/***************************************************************/

View File

@ -24,32 +24,21 @@
Konstruktor des EtherCAT-Masters.
@param master Zeiger auf den zu initialisierenden
EtherCAT-Master
@param dev Zeiger auf das EtherCAT-Gerät, mit dem der
Master arbeiten soll
EtherCAT-Master
@return 0 bei Erfolg, sonst < 0 (= dev ist NULL)
*/
int EtherCAT_master_init(EtherCAT_master_t *master,
EtherCAT_device_t *dev)
void EtherCAT_master_init(EtherCAT_master_t *master)
{
if (!dev)
{
printk(KERN_ERR "EtherCAT: Master init without device!\n");
return -1;
}
master->slaves = NULL;
master->slave_count = 0;
master->dev = dev;
master->dev = NULL;
master->command_index = 0x00;
master->tx_data_length = 0;
master->process_data = NULL;
master->process_data_length = 0;
master->debug_level = 0;
return 0;
}
/***************************************************************/
@ -79,6 +68,73 @@ void EtherCAT_master_clear(EtherCAT_master_t *master)
/***************************************************************/
/**
Setzt das EtherCAT-Geraet, auf dem der Master arbeitet.
Registriert das Geraet beim master, der es daraufhin oeffnet.
@param master Der EtherCAT-Master
@param device Das EtherCAT-Geraet
@return 0, wenn alles o.k.,
< 0, wenn bereits ein Geraet registriert
oder das Geraet nicht geoeffnet werden konnte.
*/
int EtherCAT_register_device(EtherCAT_master_t *master,
EtherCAT_device_t *device)
{
if (!master || !device)
{
printk(KERN_ERR "EtherCAT: Illegal parameters for register_device()!\n");
return -1;
}
if (master->dev)
{
printk(KERN_ERR "EtherCAT: Master already has a device.\n");
return -1;
}
if (EtherCAT_device_open(device) < 0)
{
printk(KERN_ERR "EtherCAT: Could not open device %X!\n",
(unsigned int) master->dev);
return -1;
}
master->dev = device;
return 0;
}
/***************************************************************/
/**
Loescht das EtherCAT-Geraet, auf dem der Master arbeitet.
@param master Der EtherCAT-Master
@param device Das EtherCAT-Geraet
*/
void EtherCAT_unregister_device(EtherCAT_master_t *master,
EtherCAT_device_t *device)
{
if (master->dev != device)
{
printk(KERN_WARNING "EtherCAT: Trying to unregister unknown device.\n");
return;
}
if (EtherCAT_device_close(master->dev) < 0)
{
printk(KERN_WARNING "EtherCAT: Could not close device!\n");
}
master->dev = NULL;
}
/***************************************************************/
/**
Sendet ein einzelnes Kommando in einem Frame und
wartet auf dessen Empfang.
@ -325,17 +381,9 @@ int EtherCAT_check_slaves(EtherCAT_master_t *master,
unsigned int i, j, found, length, pos;
unsigned char data[2];
// EtherCAT_clear_slaves() must be called before!
if (master->slaves || master->slave_count)
{
printk(KERN_ERR "EtherCAT duplicate slave check!");
return -1;
}
// No slaves.
if (slave_count == 0)
{
printk(KERN_ERR "EtherCAT: No slaves in list!");
printk(KERN_ERR "EtherCAT: No slaves in list!\n");
return -1;
}
@ -1090,9 +1138,13 @@ void output_debug_data(const EtherCAT_master_t *master)
EXPORT_SYMBOL(EtherCAT_master_init);
EXPORT_SYMBOL(EtherCAT_master_clear);
EXPORT_SYMBOL(EtherCAT_register_device);
EXPORT_SYMBOL(EtherCAT_unregister_device);
EXPORT_SYMBOL(EtherCAT_read_process_data);
EXPORT_SYMBOL(EtherCAT_write_process_data);
EXPORT_SYMBOL(EtherCAT_check_slaves);
EXPORT_SYMBOL(EtherCAT_activate_all_slaves);
EXPORT_SYMBOL(EtherCAT_clear_process_data);
EXPORT_SYMBOL(EtherCAT_deactivate_all_slaves);
/***************************************************************/

View File

@ -56,9 +56,13 @@ EtherCAT_master_t;
/***************************************************************/
// Master creation and deletion
int EtherCAT_master_init(EtherCAT_master_t *, EtherCAT_device_t *);
void EtherCAT_master_init(EtherCAT_master_t *);
void EtherCAT_master_clear(EtherCAT_master_t *);
// Registration of devices
int EtherCAT_register_device(EtherCAT_master_t *, EtherCAT_device_t *);
void EtherCAT_unregister_device(EtherCAT_master_t *, EtherCAT_device_t *);
// Sending and receiving
int EtherCAT_simple_send_receive(EtherCAT_master_t *, EtherCAT_command_t *);
int EtherCAT_simple_send(EtherCAT_master_t *, EtherCAT_command_t *);

142
drivers/ec_module.c Normal file
View File

@ -0,0 +1,142 @@
/******************************************************************************
*
* ec_module.c
*
* EtherCAT-Master-Treiber
*
* Autoren: Wilhelm Hagemeister, Florian Pose
*
* $Id$
*
* (C) Copyright IgH 2005
* Ingenieurgemeinschaft IgH
* Heinz-Bäcker Str. 34
* D-45356 Essen
* Tel.: +49 201/61 99 31
* Fax.: +49 201/61 98 36
* E-mail: sp@igh-essen.com
*
******************************************************************************/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include "ec_module.h"
/******************************************************************************/
#define SUBVERSION_ID "$Id$"
int ecat_master_count = 1;
EtherCAT_master_t *ecat_masters = NULL;
/******************************************************************************/
MODULE_AUTHOR ("Wilhelm Hagemeister <hm@igh-essen.com>, Florian Pose <fp@igh-essen.com>");
MODULE_DESCRIPTION ("EtherCAT master driver module");
MODULE_LICENSE("GPL");
MODULE_VERSION(SUBVERSION_ID);
module_param(ecat_master_count, int, 1);
MODULE_PARM_DESC(ecat_master_count, "Number of EtherCAT master to initialize.");
module_init(ecat_init_module);
module_exit(ecat_cleanup_module);
EXPORT_SYMBOL(EtherCAT_master);
/******************************************************************************/
/**
Init-Funktion des EtherCAT-Master-Treibermodules
Initialisiert soviele Master, wie im Parameter ecat_master_count
angegeben wurde (Default ist 1).
@returns 0, wenn alles o.k., -1 bei ungueltiger Anzahl Master
oder zu wenig Speicher.
*/
int __init ecat_init_module(void)
{
unsigned int i;
printk(KERN_ERR "EtherCAT: Master driver %s\n", SUBVERSION_ID);
if (ecat_master_count < 1)
{
printk(KERN_ERR "EtherCAT: Error - Illegal ecat_master_count: %i\n",
ecat_master_count);
return -1;
}
printk(KERN_ERR "EtherCAT: Initializing %i EtherCAT master(s)...\n",
ecat_master_count);
if ((ecat_masters = (EtherCAT_master_t *) kmalloc(sizeof(EtherCAT_master_t)
* ecat_master_count,
GFP_KERNEL)) == NULL)
{
printk(KERN_ERR "EtherCAT: Could not allocate memory for EtherCAT master(s)!\n");
return -1;
}
for (i = 0; i < ecat_master_count; i++)
{
EtherCAT_master_init(&ecat_masters[i]);
}
printk(KERN_ERR "EtherCAT: Master driver initialized.\n");
return 0;
}
/******************************************************************************/
/**
Cleanup-Funktion des EtherCAT-Master-Treibermoduls
Entfernt alle Master-Instanzen.
*/
void __exit ecat_cleanup_module(void)
{
unsigned int i;
printk(KERN_ERR "EtherCAT: Cleaning up master driver...\n");
if (ecat_masters)
{
for (i = 0; i < ecat_master_count; i++)
{
EtherCAT_master_clear(&ecat_masters[i]);
}
kfree(ecat_masters);
}
printk(KERN_ERR "EtherCAT: Master driver cleaned up.\n");
}
/******************************************************************************/
/**
Gibt einen Zeiger auf einen bestimmten EtherCAT-Master zurueck.
@param index Index des gewuenschten Masters
@returns Zeiger auf EtherCAT-Master oder NULL, wenn Parameter ungueltig.
*/
EtherCAT_master_t *EtherCAT_master(int index)
{
if (index < 0 || index >= ecat_master_count)
{
printk(KERN_ERR "EtherCAT: Master %i does not exist!\n", index);
return NULL;
}
return &ecat_masters[index];
}
/******************************************************************************/

34
drivers/ec_module.h Normal file
View File

@ -0,0 +1,34 @@
/******************************************************************************
*
* ec_module.h
*
* EtherCAT-Master-Treiber
*
* Autoren: Wilhelm Hagemeister, Florian Pose
*
* $Id$
*
* (C) Copyright IgH 2005
* Ingenieurgemeinschaft IgH
* Heinz-Bäcker Str. 34
* D-45356 Essen
* Tel.: +49 201/61 99 31
* Fax.: +49 201/61 98 36
* E-mail: sp@igh-essen.com
*
******************************************************************************/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include "ec_master.h"
/******************************************************************************/
int __init ecat_init_module(void);
void __exit ecat_cleanup_module(void);
EtherCAT_master_t *EtherCAT_master(int);
/******************************************************************************/

View File

@ -15,27 +15,17 @@
#include "../drivers/ec_master.h"
#include "../drivers/ec_device.h"
#include "../drivers/ec_types.h"
#include "../drivers/ec_module.h"
/******************************************************************************/
#define ECAT
#define ECAT_OPEN
#define ECAT_MASTER
#define ECAT_SLAVES
// Auskommentieren, wenn keine zyklischen Daten erwuenscht
#define ECAT_CYCLIC_DATA
/******************************************************************************/
#ifdef ECAT
extern EtherCAT_device_t rtl_ecat_dev;
#ifdef ECAT_MASTER
static EtherCAT_master_t *ecat_master = NULL;
#endif
#ifdef ECAT_SLAVES
static EtherCAT_slave_t ecat_slaves[] =
{
#if 0
@ -91,10 +81,6 @@ static EtherCAT_slave_t ecat_slaves[] =
#define ECAT_SLAVES_COUNT (sizeof(ecat_slaves) / sizeof(EtherCAT_slave_t))
#endif // ECAT_SLAVES
#endif // ECAT
#ifdef ECAT_CYCLIC_DATA
int value;
@ -111,7 +97,6 @@ unsigned long last_start_jiffies;
*
*****************************************************************************/
#ifdef ECAT
#ifdef ECAT_CYCLIC_DATA
static int next2004(int *wrap)
@ -138,7 +123,6 @@ static int next2004(int *wrap)
return -1;
}
#endif
#endif
/******************************************************************************
*
@ -152,7 +136,6 @@ static int next2004(int *wrap)
static void run(unsigned long data)
{
#ifdef ECAT
static int ms = 0;
static int cnt = 0;
static unsigned long int k = 0;
@ -230,7 +213,6 @@ static void run(unsigned long data)
rdtscl(k);
EtherCAT_write_process_data(ecat_master);
firstrun = 0;
#endif
timer.expires += HZ / 1000;
add_timer(&timer);
@ -246,119 +228,50 @@ static void run(unsigned long data)
int __init init_module()
{
#ifdef ECAT
#ifdef ECAT_OPEN
int rv = -1;
#endif
#endif
printk(KERN_INFO "=== Starting Minimal EtherCAT environment... ===\n");
printk(KERN_INFO "=== Starting Minimal EtherCAT environment... ===\n");
if ((ecat_master = EtherCAT_master(0)) == NULL)
{
printk(KERN_ERR "No EtherCAT master available!\n");
return -1;
}
#ifdef ECAT
printk("Checking EtherCAT slaves.\n");
EtherCAT_device_debug(&rtl_ecat_dev);
if (EtherCAT_check_slaves(ecat_master, ecat_slaves, ECAT_SLAVES_COUNT) != 0)
{
printk(KERN_ERR "EtherCAT: Could not init slaves!\n");
return -1;
}
#ifdef ECAT_OPEN
printk("Opening EtherCAT device.\n");
printk("Activating all EtherCAT slaves.\n");
// HIER PASSIERT DER FEHLER:
if (EtherCAT_device_open(&rtl_ecat_dev) < 0)
{
printk(KERN_ERR "msr_modul: Could not initialize EtherCAT NIC.\n");
goto out_nothing;
}
if (!rtl_ecat_dev.dev) // Es gibt kein EtherCAT-Device
{
printk(KERN_ERR "msr_modul: No EtherCAT device!\n");
goto out_close;
}
#endif // ECAT_OPEN
#ifdef ECAT_MASTER
printk("Initialising EtherCAT master\n");
if ((ecat_master = (EtherCAT_master_t *) kmalloc(sizeof(EtherCAT_master_t), GFP_KERNEL)) == 0)
{
printk(KERN_ERR "msr_modul: Could not alloc memory for EtherCAT master!\n");
goto out_close;
}
if (EtherCAT_master_init(ecat_master, &rtl_ecat_dev) < 0)
{
printk(KERN_ERR "EtherCAT could not init master!\n");
goto out_master;
}
//ecat_master->debug_level = 1;
#endif // ECAT_MASTER
#ifdef ECAT_SLAVES
printk("Checking EtherCAT slaves.\n");
if (EtherCAT_check_slaves(ecat_master, ecat_slaves, ECAT_SLAVES_COUNT) != 0)
{
printk(KERN_ERR "EtherCAT: Could not init slaves!\n");
goto out_masterclear;
}
printk("Activating all EtherCAT slaves.\n");
if (EtherCAT_activate_all_slaves(ecat_master) != 0)
{
printk(KERN_ERR "EtherCAT: Could not activate slaves!\n");
goto out_masterclear;
}
#endif
#endif // ECAT
if (EtherCAT_activate_all_slaves(ecat_master) != 0)
{
printk(KERN_ERR "EtherCAT: Could not activate slaves!\n");
return -1;
}
#ifdef ECAT_CYCLIC_DATA
printk("Starting cyclic sample thread.\n");
printk("Starting cyclic sample thread.\n");
schedule();
mdelay(1000);
schedule();
init_timer(&timer);
schedule();
mdelay(1000);
schedule();
init_timer(&timer);
timer.function = run;
timer.data = 0;
timer.expires = jiffies+10; // Das erste Mal sofort feuern
last_start_jiffies = timer.expires;
add_timer(&timer);
timer.function = run;
timer.data = 0;
timer.expires = jiffies+10; // Das erste Mal sofort feuern
last_start_jiffies = timer.expires;
add_timer(&timer);
printk("Initialised sample thread.\n");
printk("Initialised sample thread.\n");
#endif
printk(KERN_INFO "=== Minimal EtherCAT environment started. ===\n");
printk(KERN_INFO "=== Minimal EtherCAT environment started. ===\n");
return 0;
#ifdef ECAT
#ifdef ECAT_SLAVES
out_masterclear:
printk(KERN_INFO "Clearing EtherCAT master.\n");
EtherCAT_master_clear(ecat_master);
#endif
#ifdef ECAT_MASTER
out_master:
printk(KERN_INFO "Freeing EtherCAT master.\n");
kfree(ecat_master);
#endif
#ifdef ECAT_OPEN
out_close:
printk(KERN_INFO "Closing device.\n");
EtherCAT_device_close(&rtl_ecat_dev);
out_nothing:
return rv;
#endif
#endif // ECAT
return 0;
}
/******************************************************************************
@ -371,48 +284,16 @@ void __exit cleanup_module()
{
printk(KERN_INFO "=== Stopping Minimal EtherCAT environment... ===\n");
#ifdef ECAT_MASTER
#ifdef ECAT
if (ecat_master)
{
#endif
//ecat_master->debug_level = 1;
#ifdef ECAT_CYCLIC_DATA
del_timer_sync(&timer);
#ifdef ECAT
EtherCAT_clear_process_data(ecat_master);
#endif
del_timer_sync(&timer);
EtherCAT_clear_process_data(ecat_master);
#endif // ECAT_CYCLIC_DATA
#ifdef ECAT
#ifdef ECAT_SLAVES
printk(KERN_INFO "Deactivating slaves.\n");
EtherCAT_deactivate_all_slaves(ecat_master);
#endif
printk(KERN_INFO "Clearing EtherCAT master.\n");
EtherCAT_master_clear(ecat_master);
printk(KERN_INFO "Freeing EtherCAT master.\n");
kfree(ecat_master);
ecat_master = NULL;
printk(KERN_INFO "Deactivating slaves.\n");
EtherCAT_deactivate_all_slaves(ecat_master);
}
#endif // ECAT
#endif // ECAT_MASTER
#ifdef ECAT
#ifdef ECAT_OPEN
printk(KERN_INFO "Closing device.\n");
EtherCAT_device_close(&rtl_ecat_dev);
#endif
#endif
printk(KERN_INFO "=== Minimal EtherCAT environment stopped. ===\n");
}