Vereinheitlichte Schnittstellen, Include-Verzeichnis und Module getrennt.

This commit is contained in:
Florian Pose 2006-01-17 18:28:15 +00:00
parent 2248e19339
commit b0443360ec
30 changed files with 1558 additions and 1700 deletions

View File

@ -13,7 +13,7 @@ ifneq ($(KERNELRELEASE),)
#------------------------------------------------------------------------------
# Kbuild-Abschnitt
obj-m := drivers/ rt/ mini/
obj-m := master/ devices/ rt/ mini/
#------------------------------------------------------------------------------
@ -38,10 +38,6 @@ config conf $(CONFIG_FILE):
@echo "# EtherCAT Konfigurationsdatei Kernel 2.6" > $(CONFIG_FILE)
@echo >> $(CONFIG_FILE)
@echo "KERNELDIR = /usr/src/linux" >> $(CONFIG_FILE)
@echo "RTAIDIR =" >> $(CONFIG_FILE)
@echo "RTLIBDIR =" >> $(CONFIG_FILE)
@echo >> $(CONFIG_FILE)
@echo "MAKE_RT = yes" >> $(CONFIG_FILE)
@echo >> $(CONFIG_FILE)
@echo "$(CONFIG_FILE) erstellt."

View File

@ -109,7 +109,7 @@
*/
#define DRV_NAME "8139too_ecat"
#define DRV_NAME "8139too_ec"
#define DRV_VERSION "0.9.27"
@ -134,16 +134,14 @@
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
#include "ec_device.h"
#include "ec_master.h"
#include "ec_module.h"
#include "../include/EtherCAT_dev.h"
#define LITERAL(X) #X
#define STRINGIFY(X) LITERAL(X)
#define LIT(X) #X
#define STR(X) LIT(X)
#define COMPILE_INFO "Revision " STRINGIFY(EC_REV) \
", compiled by " STRINGIFY(EC_USER) \
" at " STRINGIFY(EC_DATE)
#define COMPILE_INFO "Revision " STR(EC_REV) \
", compiled by " STR(EC_USER) \
" at " STR(EC_DATE)
/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
@ -202,14 +200,14 @@ static int debug = -1;
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
// Uncomment for debugging
//#define ECAT_DEBUG
//#define EC_DEBUG
// 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;
int rtl_ecat_dev_registered = 0;
static ec_device_t *rtl_ec_dev;
int rtl_ec_dev_registered = 0;
/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
@ -1028,13 +1026,12 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
if (board_idx == ec_device_index)
{
printk("EtherCAT registering board %d.\n", board_idx);
{
printk(KERN_INFO "Registering EtherCAT device...\n");
rtl_ec_dev = EtherCAT_dev_register(ec_device_master_index, dev,
rtl8139_interrupt, THIS_MODULE);
if (EtherCAT_device_assign(&rtl_ecat_dev, dev) < 0)
goto err_out;
strcpy(dev->name,"ecat0"); //device name überschreiben
if (rtl_ec_dev) strcpy(dev->name, "ec0");
}
/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
@ -1095,7 +1092,7 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
/* EtherCAT-Karten nicht beim Stack anmelden. */
if (dev != rtl_ecat_dev.dev)
if (!EtherCAT_dev_is_ec(rtl_ec_dev, dev))
{
DPRINTK("About to register device named %s (%p)...\n", dev->name, dev);
i = register_netdev (dev);
@ -1193,7 +1190,7 @@ static void __devexit rtl8139_remove_one (struct pci_dev *pdev)
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
if (dev != rtl_ecat_dev.dev)
if (!EtherCAT_dev_is_ec(rtl_ec_dev, dev))
{
unregister_netdev (dev);
}
@ -1402,11 +1399,11 @@ static int rtl8139_open (struct net_device *dev)
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
#ifdef ECAT_DEBUG
#ifdef EC_DEBUG
printk(KERN_DEBUG "%s: open\n", dev->name);
#endif
if (dev != rtl_ecat_dev.dev)
if (!EtherCAT_dev_is_ec(rtl_ec_dev, dev))
{
retval = request_irq(dev->irq, rtl8139_interrupt, SA_SHIRQ, dev->name, dev);
if (retval)
@ -1423,7 +1420,7 @@ static int rtl8139_open (struct net_device *dev)
{
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
if (dev != rtl_ecat_dev.dev)
if (!EtherCAT_dev_is_ec(rtl_ec_dev, dev))
{
free_irq(dev->irq, dev);
}
@ -1448,7 +1445,7 @@ static int rtl8139_open (struct net_device *dev)
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
if (dev != rtl_ecat_dev.dev)
if (!EtherCAT_dev_is_ec(rtl_ec_dev, dev))
{
netif_start_queue (dev);
@ -1543,7 +1540,7 @@ static void rtl8139_hw_start (struct net_device *dev)
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
if (dev != rtl_ecat_dev.dev)
if (!EtherCAT_dev_is_ec(rtl_ec_dev, dev))
{
/* Enable all known interrupts by setting the interrupt mask. */
RTL_W16 (IntrMask, rtl8139_intr_mask);
@ -1807,15 +1804,9 @@ static void rtl8139_tx_timeout (struct net_device *dev)
printk(KERN_DEBUG "%s: tx_timeout\n", dev->name);
if (dev == rtl_ecat_dev.dev)
if (EtherCAT_dev_is_ec(rtl_ec_dev, dev))
{
if (rtl_ecat_dev.state != ECAT_DS_SENT)
{
printk(KERN_WARNING "EtherCAT: Wrong status at timeout: %i\n",
rtl_ecat_dev.state);
}
rtl_ecat_dev.state = ECAT_DS_TIMEOUT;
EtherCAT_dev_state(rtl_ec_dev, EC_DEVICE_STATE_TIMEOUT);
}
/* disable Tx ASAP, if not already */
@ -1823,7 +1814,7 @@ static void rtl8139_tx_timeout (struct net_device *dev)
if (tmp8 & CmdTxEnb)
RTL_W8 (ChipCmd, CmdRxEnb);
if (dev != rtl_ecat_dev.dev)
if (!EtherCAT_dev_is_ec(rtl_ec_dev, dev))
{
spin_lock(&tp->rx_lock);
@ -1873,16 +1864,16 @@ static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev)
memset(tp->tx_buf[entry], 0, ETH_ZLEN);
skb_copy_and_csum_dev(skb, tp->tx_buf[entry]);
if (dev != rtl_ecat_dev.dev) dev_kfree_skb(skb);
if (!EtherCAT_dev_is_ec(rtl_ec_dev, dev)) dev_kfree_skb(skb);
}
else
{
if (dev != rtl_ecat_dev.dev) dev_kfree_skb(skb);
if (!EtherCAT_dev_is_ec(rtl_ec_dev, dev)) dev_kfree_skb(skb);
tp->stats.tx_dropped++;
return 0;
}
if (dev != rtl_ecat_dev.dev)
if (!EtherCAT_dev_is_ec(rtl_ec_dev, dev))
{
spin_lock_irq(&tp->lock);
}
@ -1899,7 +1890,7 @@ static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev)
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
if (dev != rtl_ecat_dev.dev)
if (!EtherCAT_dev_is_ec(rtl_ec_dev, dev))
{
if ((tp->cur_tx - NUM_TX_DESC) == tp->dirty_tx)
netif_stop_queue (dev);
@ -1931,11 +1922,13 @@ static void rtl8139_tx_interrupt (struct net_device *dev,
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
if (dev == rtl_ecat_dev.dev)
{
rtl_ecat_dev.tx_intr_cnt++;
rdtscl(rtl_ecat_dev.tx_time); // Get CPU cycles
#if 0
if (EtherCAT_dev_is_ec(rtl_ec_dev, dev))
{
rtl_ec_dev.tx_intr_cnt++;
rdtscl(rtl_ec_dev.tx_time); // Get CPU cycles
}
#endif
/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
@ -1968,9 +1961,9 @@ static void rtl8139_tx_interrupt (struct net_device *dev,
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
if (dev == rtl_ecat_dev.dev)
if (EtherCAT_dev_is_ec(rtl_ec_dev, dev))
{
rtl_ecat_dev.state = ECAT_DS_ERROR;
EtherCAT_dev_state(rtl_ec_dev, EC_DEVICE_STATE_ERROR);
}
/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
@ -1994,7 +1987,7 @@ static void rtl8139_tx_interrupt (struct net_device *dev,
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
#ifndef RTL8139_NDEBUG
if (dev != rtl_ecat_dev.dev && tp->cur_tx - dirty_tx > NUM_TX_DESC) {
if (!EtherCAT_dev_is_ec(rtl_ec_dev, dev) && tp->cur_tx - dirty_tx > NUM_TX_DESC) {
printk (KERN_ERR "%s: Out-of-sync dirty pointer, %ld vs. %ld.\n",
dev->name, dirty_tx, tp->cur_tx);
dirty_tx += NUM_TX_DESC;
@ -2010,7 +2003,7 @@ static void rtl8139_tx_interrupt (struct net_device *dev,
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
if (dev != rtl_ecat_dev.dev)
if (!EtherCAT_dev_is_ec(rtl_ec_dev, dev))
{
netif_wake_queue (dev);
}
@ -2051,9 +2044,9 @@ static void rtl8139_rx_err (u32 rx_status, struct net_device *dev,
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
if (dev == rtl_ecat_dev.dev)
if (EtherCAT_dev_is_ec(rtl_ec_dev, dev))
{
rtl_ecat_dev.state = ECAT_DS_ERROR;
EtherCAT_dev_state(rtl_ec_dev, EC_DEVICE_STATE_ERROR);
}
/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
@ -2159,16 +2152,17 @@ static int rtl8139_rx(struct net_device *dev, struct rtl8139_private *tp,
RTL_R16 (RxBufPtr), RTL_R8 (ChipCmd));
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
if (dev == rtl_ecat_dev.dev)
#if 0
if (EtherCAT_dev_is_ec(rtl_ec_dev, dev))
{
rtl_ecat_dev.rx_intr_cnt++;
rdtscl(rtl_ecat_dev.rx_time); // Get CPU cycles
rtl_ec_dev.rx_intr_cnt++;
rdtscl(rtl_ec_dev.rx_time); // Get CPU cycles
}
#endif
/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
while ((dev == rtl_ecat_dev.dev || netif_running(dev))
while ((EtherCAT_dev_is_ec(rtl_ec_dev, dev) || netif_running(dev))
&& received < budget
&& (RTL_R8 (ChipCmd) & RxBufEmpty) == 0) {
u32 ring_offset = cur_rx % RX_BUF_LEN;
@ -2185,7 +2179,7 @@ static int rtl8139_rx(struct net_device *dev, struct rtl8139_private *tp,
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
if (dev != rtl_ecat_dev.dev && netif_msg_rx_status(tp))
if (!EtherCAT_dev_is_ec(rtl_ec_dev, dev) && netif_msg_rx_status(tp))
printk(KERN_DEBUG "%s: rtl8139_rx() status %4.4x, size %4.4x,"
" cur %4.4x.\n", dev->name, rx_status,
rx_size, cur_rx);
@ -2241,7 +2235,7 @@ no_early_rx:
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
if (dev != rtl_ecat_dev.dev)
if (!EtherCAT_dev_is_ec(rtl_ec_dev, dev))
{
/* Malloc up new buffer, compatible with net-2e. */
/* Omit the four octet CRC from the length. */
@ -2274,23 +2268,14 @@ no_early_rx:
}
else
{
if (rtl_ecat_dev.state != ECAT_DS_SENT)
{
printk(KERN_WARNING "EtherCAT: Received frame while not in SENT state!\n");
}
else
{
// Copy received data to ethercat-device buffer, skip Ethernet-II header
memcpy(rtl_ecat_dev.rx_data, &rx_ring[ring_offset + 4] + ETH_HLEN,
pkt_size - ETH_HLEN);
rtl_ecat_dev.rx_data_length = pkt_size - ETH_HLEN;
rtl_ecat_dev.state = ECAT_DS_RECEIVED;
dev->last_rx = jiffies;
tp->stats.rx_bytes += pkt_size;
tp->stats.rx_packets++;
}
if (EtherCAT_dev_receive(rtl_ec_dev,
&rx_ring[ring_offset + 4] + ETH_HLEN,
pkt_size - ETH_HLEN) == 0)
{
dev->last_rx = jiffies;
tp->stats.rx_bytes += pkt_size;
tp->stats.rx_packets++;
}
}
/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
@ -2415,9 +2400,11 @@ irqreturn_t rtl8139_interrupt (int irq, void *dev_instance,
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
if (dev == rtl_ecat_dev.dev)
if (EtherCAT_dev_is_ec(rtl_ec_dev, dev))
{
rtl_ecat_dev.intr_cnt++;
#if 0 // FIXME
rtl_ec_dev.intr_cnt++;
#endif
status = RTL_R16 (IntrStatus);
}
else
@ -2440,7 +2427,7 @@ irqreturn_t rtl8139_interrupt (int irq, void *dev_instance,
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
if (dev != rtl_ecat_dev.dev)
if (!EtherCAT_dev_is_ec(rtl_ec_dev, dev))
{
/* close possible race's with dev_close */
if (unlikely(!netif_running(dev))) {
@ -2459,7 +2446,6 @@ irqreturn_t rtl8139_interrupt (int irq, void *dev_instance,
ackstat = status & ~(RxAckBits | TxErr);
if (ackstat) {
RTL_W16 (IntrStatus, ackstat);
//printk("ECAT-NIC ack\n"); //HM
}
/* Receive packets are processed by poll routine.
@ -2469,7 +2455,7 @@ irqreturn_t rtl8139_interrupt (int irq, void *dev_instance,
if (status & RxAckBits)
{
if (dev != rtl_ecat_dev.dev)
if (!EtherCAT_dev_is_ec(rtl_ec_dev, dev))
{
/* Polling vormerken */
if (netif_rx_schedule_prep(dev)) {
@ -2499,7 +2485,7 @@ irqreturn_t rtl8139_interrupt (int irq, void *dev_instance,
out:
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
if (dev != rtl_ecat_dev.dev)
if (!EtherCAT_dev_is_ec(rtl_ec_dev, dev))
{
spin_unlock (&tp->lock);
}
@ -2533,7 +2519,7 @@ static int rtl8139_close (struct net_device *dev)
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
if (dev != rtl_ecat_dev.dev)
if (!EtherCAT_dev_is_ec(rtl_ec_dev, dev))
{
netif_stop_queue(dev);
if (tp->thr_pid >= 0) {
@ -2798,7 +2784,7 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
if (dev == rtl_ecat_dev.dev || !netif_running(dev))
if (EtherCAT_dev_is_ec(rtl_ec_dev, dev) || !netif_running(dev))
return -EINVAL;
/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
@ -2819,7 +2805,7 @@ static struct net_device_stats *rtl8139_get_stats (struct net_device *dev)
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
if (dev == rtl_ecat_dev.dev || netif_running(dev))
if (EtherCAT_dev_is_ec(rtl_ec_dev, dev) || netif_running(dev))
{
spin_lock_irqsave (&tp->lock, flags);
tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
@ -2906,7 +2892,7 @@ static int rtl8139_suspend (struct pci_dev *pdev, pm_message_t state)
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
if (dev == rtl_ecat_dev.dev || !netif_running (dev))
if (EtherCAT_dev_is_ec(rtl_ec_dev, dev) || !netif_running (dev))
return 0;
/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
@ -2939,7 +2925,7 @@ static int rtl8139_resume (struct pci_dev *pdev)
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
if (dev == rtl_ecat_dev.dev || !netif_running (dev))
if (EtherCAT_dev_is_ec(rtl_ec_dev, dev) || !netif_running (dev))
return 0;
/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
@ -2975,69 +2961,54 @@ static int __init rtl8139_init_module (void)
printk (KERN_INFO RTL8139_DRIVER_NAME "\n");
#endif
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
printk(KERN_INFO "Initializing RTL8139-EtherCAT module. %s\n", COMPILE_INFO);
printk(KERN_INFO "Initializing RTL8139-EtherCAT module. %s\n", COMPILE_INFO);
printk(KERN_INFO "EtherCAT device index is %i.\n", ec_device_index);
EtherCAT_device_init(&rtl_ecat_dev);
rtl_ecat_dev.isr = rtl8139_interrupt;
rtl_ecat_dev.module = THIS_MODULE;
if (pci_module_init(&rtl8139_pci_driver) < 0)
{
printk(KERN_ERR "Could not init PCI module.\n");
goto out_ec_dev;
}
if (pci_module_init(&rtl8139_pci_driver) < 0)
{
printk(KERN_ERR "Could not init PCI module.\n");
return -1;
}
if (!rtl_ec_dev)
{
printk(KERN_WARNING "NO EtherCAT device registered!\n");
}
printk(KERN_INFO "EtherCAT device index is %i.\n", ec_device_index);
return 0;
if (rtl_ecat_dev.dev)
{
printk(KERN_INFO "Registering EtherCAT device...\n");
if (EtherCAT_register_device(ec_device_master_index, &rtl_ecat_dev) < 0)
{
printk(KERN_ERR "Could not register device.\n");
goto out_module;
}
out_ec_dev:
if (rtl_ec_dev) {
printk(KERN_INFO "Unregistering RTL8139-EtherCAT device...\n");
EtherCAT_dev_unregister(ec_device_master_index);
rtl_ec_dev = NULL;
}
rtl_ecat_dev_registered = 1;
return -1;
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 <<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
}
static void __exit rtl8139_cleanup_module (void)
{
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
printk(KERN_INFO "Cleaning up RTL8139-EtherCAT module...\n");
printk(KERN_INFO "Cleaning up RTL8139-EtherCAT module...\n");
if (rtl_ecat_dev_registered && rtl_ecat_dev.dev)
{
printk(KERN_INFO "Unregistering RTL8139-EtherCAT device...\n");
EtherCAT_unregister_device(ec_device_master_index, &rtl_ecat_dev);
}
if (rtl_ec_dev) {
printk(KERN_INFO "Unregistering RTL8139-EtherCAT device...\n");
EtherCAT_dev_unregister(ec_device_master_index);
rtl_ec_dev = NULL;
}
pci_unregister_driver(&rtl8139_pci_driver);
EtherCAT_device_clear(&rtl_ecat_dev);
pci_unregister_driver(&rtl8139_pci_driver);
printk(KERN_INFO "RTL8139-EtherCAT module cleaned up.\n");
printk(KERN_INFO "RTL8139-EtherCAT module cleaned up.\n");
/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
}

46
devices/Makefile Normal file
View File

@ -0,0 +1,46 @@
#------------------------------------------------------------------------------
#
# Makefile
#
# IgH EtherCAT-Treiber - EtherCAT Geraete
#
# $Id$
#
#------------------------------------------------------------------------------
ifneq ($(KERNELRELEASE),)
#------------------------------------------------------------------------------
# Kbuild-Abschnitt
obj-m := ec_8139too.o
ec_8139too-objs := 8139too.o
REV = `svnversion $(src)`
DATE = `date`
EXTRA_CFLAGS = -DEC_REV="$(REV)" -DEC_USER="$(USER)" -DEC_DATE="$(DATE)"
#------------------------------------------------------------------------------
else
#------------------------------------------------------------------------------
# Default-Abschnitt
ifneq ($(wildcard ethercat.conf),)
include ethercat.conf
else
KERNELDIR = /lib/modules/`uname -r`/build
endif
modules:
$(MAKE) -C $(KERNELDIR) M=`pwd` modules
clean:
$(MAKE) -C $(KERNELDIR) M=`pwd` clean
#------------------------------------------------------------------------------
endif

View File

@ -1,17 +0,0 @@
/******************************************************************************
*
* E t h e r C A T . h
*
* Header zur Nutzung der EtherCAT-Funktionen.
*
* $Id$
*
*****************************************************************************/
#include "../drivers/ec_master.h"
#include "../drivers/ec_device.h"
#include "../drivers/ec_types.h"
#include "../drivers/ec_module.h"
/*****************************************************************************/

View File

@ -1,124 +0,0 @@
/******************************************************************************
*
* e c _ c o m m a n d . h
*
* Struktur für ein EtherCAT-Kommando.
*
* $Id$
*
*****************************************************************************/
#ifndef _EC_COMMAND_H_
#define _EC_COMMAND_H_
#include "ec_globals.h"
/*****************************************************************************/
/**
Status eines EtherCAT-Kommandos.
*/
typedef enum
{
ECAT_CS_READY, ECAT_CS_SENT, ECAT_CS_RECEIVED
}
EtherCAT_command_state_t;
/*****************************************************************************/
/**
EtherCAT-Adresse.
Im EtherCAT-Rahmen sind 4 Bytes für die Adresse reserviert, die
ja nach Kommandoty eine andere bedeutung haben: Bei Autoinkrement-
befehlen sind die ersten zwei Bytes die (negative)
Autoinkrement-Adresse, bei Knoten-adressierten Befehlen entsprechen
sie der Knotenadresse. Das dritte und vierte Byte entspricht in
diesen Fällen der physikalischen Speicheradresse auf dem Slave.
Bei einer logischen Adressierung entsprechen alle vier Bytes
der logischen Adresse.
*/
typedef union
{
struct
{
union
{
short pos; /**< (Negative) Ring-Position des Slaves */
unsigned short node; /**< Konfigurierte Knotenadresse */
}
dev;
unsigned short mem; /**< Physikalische Speicheradresse im Slave */
}
phy;
unsigned long logical; /**< Logische Adresse */
unsigned char raw[4]; /**< Rohdaten für die Generierung des Frames */
}
EtherCAT_address_t;
/*****************************************************************************/
/**
EtherCAT-Kommando.
*/
typedef struct EtherCAT_command
{
EtherCAT_cmd_type_t type; /**< Typ des Kommandos (APRD, NPWR, etc...) */
EtherCAT_address_t address; /**< Adresse des/der Empfänger */
unsigned int data_length; /**< Länge der zu sendenden und/oder
empfangenen Daten */
EtherCAT_command_state_t state; /**< Zustand des Kommandos
(bereit, gesendet, etc...) */
unsigned char index; /**< Kommando-Index, mit der das Kommando gesendet
wurde (wird vom Master beim Senden gesetzt. */
unsigned int working_counter; /**< Working-Counter bei Empfang (wird
vom Master gesetzt) */
unsigned char data[ECAT_FRAME_BUFFER_SIZE]; /**< Kommandodaten */
}
EtherCAT_command_t;
/*****************************************************************************/
void EtherCAT_command_init(EtherCAT_command_t *);
void EtherCAT_command_clear(EtherCAT_command_t *);
void EtherCAT_command_read(EtherCAT_command_t *,
unsigned short,
unsigned short,
unsigned int);
void EtherCAT_command_write(EtherCAT_command_t *,
unsigned short,
unsigned short,
unsigned int,
const unsigned char *);
void EtherCAT_command_position_read(EtherCAT_command_t *,
short,
unsigned short,
unsigned int);
void EtherCAT_command_position_write(EtherCAT_command_t *,
short,
unsigned short,
unsigned int,
const unsigned char *);
void EtherCAT_command_broadcast_read(EtherCAT_command_t *,
unsigned short,
unsigned int);
void EtherCAT_command_broadcast_write(EtherCAT_command_t *,
unsigned short,
unsigned int,
const unsigned char *);
void EtherCAT_command_logical_read_write(EtherCAT_command_t *,
unsigned int,
unsigned int,
unsigned char *);
/*****************************************************************************/
#endif

View File

@ -1,81 +0,0 @@
/******************************************************************************
*
* e c _ g l o b a l s . h
*
* Globale Definitionen und Makros für das EtherCAT-Protokoll.
*
* $Id$
*
*****************************************************************************/
#ifndef _EC_GLOBALS_
#define _EC_GLOBALS_
/*****************************************************************************/
/**
Maximale Größe eines EtherCAT-Frames
*/
#define ECAT_FRAME_BUFFER_SIZE 1500
/**
Maximale Anzahl der Prozessdatendomänen in einem Master
*/
#define ECAT_MAX_DOMAINS 10
/**
NULL-Define, falls noch nicht definiert.
*/
#ifndef NULL
#define NULL ((void *) 0)
#endif
/*****************************************************************************/
/**
EtherCAT-Kommando-Typ
*/
typedef enum
{
ECAT_CMD_NONE = 0x00, /**< Dummy */
ECAT_CMD_APRD = 0x01, /**< Auto-increment physical read */
ECAT_CMD_APWR = 0x02, /**< Auto-increment physical write */
ECAT_CMD_NPRD = 0x04, /**< Node-addressed physical read */
ECAT_CMD_NPWR = 0x05, /**< Node-addressed physical write */
ECAT_CMD_BRD = 0x07, /**< Broadcast read */
ECAT_CMD_BWR = 0x08, /**< Broadcast write */
ECAT_CMD_LRW = 0x0C /**< Logical read/write */
}
EtherCAT_cmd_type_t;
/*****************************************************************************/
/**
Zustand eines EtherCAT-Slaves
*/
typedef enum
{
ECAT_STATE_UNKNOWN = 0x00, /**< Status unbekannt */
ECAT_STATE_INIT = 0x01, /**< Init-Zustand (Keine Mailbox-
Kommunikation, Kein I/O) */
ECAT_STATE_PREOP = 0x02, /**< Pre-Operational (Mailbox-
Kommunikation, Kein I/O) */
ECAT_STATE_SAVEOP = 0x04, /**< Save-Operational (Mailbox-
Kommunikation und Input Update) */
ECAT_STATE_OP = 0x08, /**< Operational, (Mailbox-
Kommunikation und Input/Output Update) */
ECAT_ACK_STATE = 0x10 /**< Acknoledge-Bit beim Zustandswechsel
(dies ist kein eigener Zustand) */
}
EtherCAT_state_t;
/*****************************************************************************/
typedef struct EtherCAT_master EtherCAT_master_t;
/*****************************************************************************/
#endif

View File

@ -1,96 +0,0 @@
/******************************************************************************
*
* e c _ m a s t e r . h
*
* Struktur für einen EtherCAT-Master.
*
* $Id$
*
*****************************************************************************/
#ifndef _EC_MASTER_H_
#define _EC_MASTER_H_
#include "ec_device.h"
#include "ec_slave.h"
#include "ec_command.h"
#include "ec_domain.h"
/*****************************************************************************/
/**
EtherCAT-Master
Verwaltet die EtherCAT-Slaves und kommuniziert mit
dem zugewiesenen EtherCAT-Gerät.
*/
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
für zu sendende Daten */
unsigned int tx_data_length; /**< Länge der Daten im Sendespeicher */
unsigned char rx_data[ECAT_FRAME_BUFFER_SIZE]; /**< Statische Speicher für
eine Kopie des Rx-Buffers
im EtherCAT-Gerät */
unsigned int rx_data_length; /**< Länge der Daten im Empfangsspeicher */
EtherCAT_domain_t domains[ECAT_MAX_DOMAINS]; /** Prozessdatendomänen */
unsigned int domain_count;
int debug_level; /**< Debug-Level im Master-Code */
unsigned int bus_time; /**< Letzte Bus-Zeit in Mikrosekunden */
unsigned int frames_lost; /**< Anzahl verlorene Frames */
unsigned long t_lost_output; /*<< Timer-Ticks bei der letzten Ausgabe von
verlorenen Frames */
};
/*****************************************************************************/
// 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 *);
// Registration of devices
int EtherCAT_master_open(EtherCAT_master_t *, EtherCAT_device_t *);
void EtherCAT_master_close(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 *);
int EtherCAT_simple_receive(EtherCAT_master_t *, EtherCAT_command_t *);
// Slave management
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_state_change(EtherCAT_master_t *, EtherCAT_slave_t *,
unsigned char);
// Misc.
void output_debug_data(const EtherCAT_master_t *);
void ecat_output_lost_frames(EtherCAT_master_t *);
/*****************************************************************************/
#endif
/* Emacs-Konfiguration
;;; Local Variables: ***
;;; c-basic-offset:2 ***
;;; End: ***
*/

View File

@ -1,36 +0,0 @@
/******************************************************************************
*
* 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"
/*****************************************************************************/
// Registration of devices
int EtherCAT_register_device(int, EtherCAT_device_t *);
void EtherCAT_unregister_device(int, EtherCAT_device_t *);
EtherCAT_master_t *EtherCAT_request(int);
void EtherCAT_release(EtherCAT_master_t *);
/*****************************************************************************/

42
include/EtherCAT_dev.h Normal file
View File

@ -0,0 +1,42 @@
/******************************************************************************
*
* Oeffentliche EtherCAT-Schnittstellen fuer EtherCAT-Geraetetreiber.
*
* $Id$
*
*****************************************************************************/
#ifndef _ETHERCAT_DEVICE_H_
#define _ETHERCAT_DEVICE_H_
#include <linux/netdevice.h>
/*****************************************************************************/
struct ec_device;
typedef struct ec_device ec_device_t;
/*****************************************************************************/
typedef enum
{
EC_DEVICE_STATE_READY, EC_DEVICE_STATE_SENT, EC_DEVICE_STATE_RECEIVED,
EC_DEVICE_STATE_TIMEOUT, EC_DEVICE_STATE_ERROR
}
ec_device_state_t;
/*****************************************************************************/
ec_device_t *EtherCAT_dev_register(unsigned int, struct net_device *,
irqreturn_t (*)(int, void *,
struct pt_regs *),
struct module *);
void EtherCAT_dev_unregister(unsigned int);
int EtherCAT_dev_is_ec(ec_device_t *, struct net_device *);
void EtherCAT_dev_state(ec_device_t *, ec_device_state_t);
int EtherCAT_dev_receive(ec_device_t *, void *, unsigned int);
/*****************************************************************************/
#endif

36
include/EtherCAT_rt.h Normal file
View File

@ -0,0 +1,36 @@
/******************************************************************************
*
* Oeffentliche EtherCAT-Schnittstellen fuer Echtzeitprozesse.
*
* $Id$
*
*****************************************************************************/
#ifndef _ETHERCAT_RT_H_
#define _ETHERCAT_RT_H_
/*****************************************************************************/
struct ec_master;
typedef struct ec_master ec_master_t;
/*****************************************************************************/
ec_master_t *EtherCAT_rt_request_master(unsigned int master_index);
void EtherCAT_rt_release_master(ec_master_t *master);
void *EtherCAT_rt_register_slave(ec_master_t *master, unsigned int slave_index,
const char *vendor_name,
const char *product_name);
int EtherCAT_rt_activate_slaves(ec_master_t *master);
int EtherCAT_rt_deactivate_slaves(ec_master_t *master);
int EtherCAT_rt_domain_cycle(ec_master_t *master, unsigned int domain,
unsigned int timeout_us);
/*****************************************************************************/
#endif

View File

@ -13,12 +13,9 @@ ifneq ($(KERNELRELEASE),)
#------------------------------------------------------------------------------
# Kbuild-Abschnitt
obj-m := 8139too-ecat.o ecat-master.o
obj-m := ec_master.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 ec_domain.o
ec_master-objs := module.o master.o device.o slave.o command.o types.o domain.o
REV = `svnversion $(src)`
DATE = `date`

View File

@ -1,6 +1,6 @@
/******************************************************************************
*
* e c _ c o m m a n d . c
* c o m m a n d . c
*
* Methoden für ein EtherCAT-Kommando.
*
@ -10,7 +10,7 @@
#include <linux/slab.h>
#include "ec_command.h"
#include "command.h"
/*****************************************************************************/
@ -23,12 +23,12 @@
@param cmd Zeiger auf das zu initialisierende Kommando.
*/
void EtherCAT_command_init(EtherCAT_command_t *cmd)
void ec_command_init(ec_command_t *cmd)
{
cmd->type = ECAT_CMD_NONE;
cmd->type = EC_COMMAND_NONE;
cmd->address.logical = 0x00000000;
cmd->data_length = 0;
cmd->state = ECAT_CS_READY;
cmd->state = EC_COMMAND_STATE_READY;
cmd->index = 0;
cmd->working_counter = 0;
}
@ -43,21 +43,21 @@ void EtherCAT_command_init(EtherCAT_command_t *cmd)
@param cmd Zeiger auf das zu initialisierende Kommando.
*/
void EtherCAT_command_clear(EtherCAT_command_t *cmd)
void ec_command_clear(ec_command_t *cmd)
{
EtherCAT_command_init(cmd);
ec_command_init(cmd);
}
/*****************************************************************************/
#define ECAT_FUNC_HEADER \
EtherCAT_command_init(cmd)
#define EC_FUNC_HEADER \
ec_command_init(cmd)
#define ECAT_FUNC_WRITE_FOOTER \
#define EC_FUNC_WRITE_FOOTER \
cmd->data_length = length; \
memcpy(cmd->data, data, length);
#define ECAT_FUNC_READ_FOOTER \
#define EC_FUNC_READ_FOOTER \
cmd->data_length = length;
/*****************************************************************************/
@ -71,21 +71,19 @@ void EtherCAT_command_clear(EtherCAT_command_t *cmd)
@param length Länge der zu lesenden Daten
*/
void EtherCAT_command_read(EtherCAT_command_t *cmd,
unsigned short node_address,
unsigned short offset,
unsigned int length)
void ec_command_read(ec_command_t *cmd, unsigned short node_address,
unsigned short offset, unsigned int length)
{
if (unlikely(node_address == 0x0000))
printk(KERN_WARNING "EtherCAT: Warning - Using node address 0x0000!\n");
ECAT_FUNC_HEADER;
EC_FUNC_HEADER;
cmd->type = ECAT_CMD_NPRD;
cmd->type = EC_COMMAND_NPRD;
cmd->address.phy.dev.node = node_address;
cmd->address.phy.mem = offset;
ECAT_FUNC_READ_FOOTER;
EC_FUNC_READ_FOOTER;
}
/*****************************************************************************/
@ -103,22 +101,20 @@ void EtherCAT_command_read(EtherCAT_command_t *cmd,
@param data Zeiger auf Speicher mit zu schreibenden Daten
*/
void EtherCAT_command_write(EtherCAT_command_t *cmd,
unsigned short node_address,
unsigned short offset,
unsigned int length,
const unsigned char *data)
void ec_command_write(ec_command_t *cmd, unsigned short node_address,
unsigned short offset, unsigned int length,
const unsigned char *data)
{
if (unlikely(node_address == 0x0000))
printk(KERN_WARNING "EtherCAT: Warning - Using node address 0x0000!\n");
ECAT_FUNC_HEADER;
EC_FUNC_HEADER;
cmd->type = ECAT_CMD_NPWR;
cmd->type = EC_COMMAND_NPWR;
cmd->address.phy.dev.node = node_address;
cmd->address.phy.mem = offset;
ECAT_FUNC_WRITE_FOOTER;
EC_FUNC_WRITE_FOOTER;
}
/*****************************************************************************/
@ -135,18 +131,16 @@ void EtherCAT_command_write(EtherCAT_command_t *cmd,
@param length Länge der zu lesenden Daten
*/
void EtherCAT_command_position_read(EtherCAT_command_t *cmd,
short ring_position,
unsigned short offset,
unsigned int length)
void ec_command_position_read(ec_command_t *cmd, short ring_position,
unsigned short offset, unsigned int length)
{
ECAT_FUNC_HEADER;
EC_FUNC_HEADER;
cmd->type = ECAT_CMD_APRD;
cmd->type = EC_COMMAND_APRD;
cmd->address.phy.dev.pos = ring_position;
cmd->address.phy.mem = offset;
ECAT_FUNC_READ_FOOTER;
EC_FUNC_READ_FOOTER;
}
/*****************************************************************************/
@ -164,19 +158,17 @@ void EtherCAT_command_position_read(EtherCAT_command_t *cmd,
@param data Zeiger auf Speicher mit zu schreibenden Daten
*/
void EtherCAT_command_position_write(EtherCAT_command_t *cmd,
short ring_position,
unsigned short offset,
unsigned int length,
const unsigned char *data)
void ec_command_position_write(ec_command_t *cmd, short ring_position,
unsigned short offset, unsigned int length,
const unsigned char *data)
{
ECAT_FUNC_HEADER;
EC_FUNC_HEADER;
cmd->type = ECAT_CMD_APWR;
cmd->type = EC_COMMAND_APWR;
cmd->address.phy.dev.pos = ring_position;
cmd->address.phy.mem = offset;
ECAT_FUNC_WRITE_FOOTER;
EC_FUNC_WRITE_FOOTER;
}
/*****************************************************************************/
@ -192,17 +184,16 @@ void EtherCAT_command_position_write(EtherCAT_command_t *cmd,
@param length Länge der zu lesenden Daten
*/
void EtherCAT_command_broadcast_read(EtherCAT_command_t *cmd,
unsigned short offset,
unsigned int length)
void ec_command_broadcast_read(ec_command_t *cmd, unsigned short offset,
unsigned int length)
{
ECAT_FUNC_HEADER;
EC_FUNC_HEADER;
cmd->type = ECAT_CMD_BRD;
cmd->type = EC_COMMAND_BRD;
cmd->address.phy.dev.node = 0x0000;
cmd->address.phy.mem = offset;
ECAT_FUNC_READ_FOOTER;
EC_FUNC_READ_FOOTER;
}
/*****************************************************************************/
@ -219,18 +210,16 @@ void EtherCAT_command_broadcast_read(EtherCAT_command_t *cmd,
@param data Zeiger auf Speicher mit zu schreibenden Daten
*/
void EtherCAT_command_broadcast_write(EtherCAT_command_t *cmd,
unsigned short offset,
unsigned int length,
const unsigned char *data)
void ec_command_broadcast_write(ec_command_t *cmd, unsigned short offset,
unsigned int length, const unsigned char *data)
{
ECAT_FUNC_HEADER;
EC_FUNC_HEADER;
cmd->type = ECAT_CMD_BWR;
cmd->type = EC_COMMAND_BWR;
cmd->address.phy.dev.node = 0x0000;
cmd->address.phy.mem = offset;
ECAT_FUNC_WRITE_FOOTER;
EC_FUNC_WRITE_FOOTER;
}
/*****************************************************************************/
@ -247,17 +236,15 @@ void EtherCAT_command_broadcast_write(EtherCAT_command_t *cmd,
@param data Zeiger auf Speicher mit zu lesenden/schreibenden Daten
*/
void EtherCAT_command_logical_read_write(EtherCAT_command_t *cmd,
unsigned int offset,
unsigned int length,
unsigned char *data)
void ec_command_logical_read_write(ec_command_t *cmd, unsigned int offset,
unsigned int length, unsigned char *data)
{
ECAT_FUNC_HEADER;
EC_FUNC_HEADER;
cmd->type = ECAT_CMD_LRW;
cmd->type = EC_COMMAND_LRW;
cmd->address.logical = offset;
ECAT_FUNC_WRITE_FOOTER;
EC_FUNC_WRITE_FOOTER;
}
/*****************************************************************************/

103
master/command.h Normal file
View File

@ -0,0 +1,103 @@
/******************************************************************************
*
* c o m m a n d . h
*
* Struktur für ein EtherCAT-Kommando.
*
* $Id$
*
*****************************************************************************/
#ifndef _EC_COMMAND_H_
#define _EC_COMMAND_H_
#include "globals.h"
/*****************************************************************************/
/**
Status eines EtherCAT-Kommandos.
*/
typedef enum
{
EC_COMMAND_STATE_READY, EC_COMMAND_STATE_SENT, EC_COMMAND_STATE_RECEIVED
}
ec_command_state_t;
/*****************************************************************************/
/**
EtherCAT-Adresse.
Im EtherCAT-Rahmen sind 4 Bytes für die Adresse reserviert, die
ja nach Kommandoty eine andere bedeutung haben: Bei Autoinkrement-
befehlen sind die ersten zwei Bytes die (negative)
Autoinkrement-Adresse, bei Knoten-adressierten Befehlen entsprechen
sie der Knotenadresse. Das dritte und vierte Byte entspricht in
diesen Fällen der physikalischen Speicheradresse auf dem Slave.
Bei einer logischen Adressierung entsprechen alle vier Bytes
der logischen Adresse.
*/
typedef union
{
struct
{
union
{
short pos; /**< (Negative) Ring-Position des Slaves */
unsigned short node; /**< Konfigurierte Knotenadresse */
}
dev;
unsigned short mem; /**< Physikalische Speicheradresse im Slave */
}
phy;
unsigned long logical; /**< Logische Adresse */
unsigned char raw[4]; /**< Rohdaten für die Generierung des Frames */
}
ec_address_t;
/*****************************************************************************/
/**
EtherCAT-Kommando.
*/
typedef struct ec_command
{
ec_command_type_t type; /**< Typ des Kommandos (APRD, NPWR, etc...) */
ec_address_t address; /**< Adresse des/der Empfänger */
unsigned int data_length; /**< Länge der zu sendenden und/oder
empfangenen Daten */
ec_command_state_t state; /**< Zustand des Kommandos
(bereit, gesendet, etc...) */
unsigned char index; /**< Kommando-Index, mit der das Kommando gesendet
wurde (wird vom Master beim Senden gesetzt. */
unsigned int working_counter; /**< Working-Counter bei Empfang (wird
vom Master gesetzt) */
unsigned char data[EC_FRAME_SIZE]; /**< Kommandodaten */
}
ec_command_t;
/*****************************************************************************/
void ec_command_read(ec_command_t *, unsigned short, unsigned short,
unsigned int);
void ec_command_write(ec_command_t *, unsigned short, unsigned short,
unsigned int, const unsigned char *);
void ec_command_position_read(ec_command_t *, short, unsigned short,
unsigned int);
void ec_command_position_write(ec_command_t *, short, unsigned short,
unsigned int, const unsigned char *);
void ec_command_broadcast_read(ec_command_t *, unsigned short, unsigned int);
void ec_command_broadcast_write(ec_command_t *, unsigned short, unsigned int,
const unsigned char *);
void ec_command_logical_read_write(ec_command_t *, unsigned int, unsigned int,
unsigned char *);
/*****************************************************************************/
#endif

View File

@ -1,6 +1,6 @@
/******************************************************************************
*
* e c _ d e v i c e . c
* d e v i c e . c
*
* Methoden für ein EtherCAT-Gerät.
*
@ -14,7 +14,7 @@
#include <linux/netdevice.h>
#include <linux/delay.h>
#include "ec_device.h"
#include "device.h"
/*****************************************************************************/
@ -27,21 +27,34 @@
@param ecd Zu initialisierendes EtherCAT-Gerät
*/
void EtherCAT_device_init(EtherCAT_device_t *ecd)
int ec_device_init(ec_device_t *ecd)
{
ecd->dev = NULL;
ecd->tx_skb = NULL;
ecd->rx_skb = NULL;
ecd->open = 0;
ecd->tx_time = 0;
ecd->rx_time = 0;
ecd->tx_intr_cnt = 0;
ecd->rx_intr_cnt = 0;
ecd->intr_cnt = 0;
ecd->state = ECAT_DS_READY;
ecd->state = EC_DEVICE_STATE_READY;
ecd->rx_data_length = 0;
ecd->isr = NULL;
ecd->module = NULL;
ecd->error_reported = 0;
if ((ecd->tx_skb = dev_alloc_skb(EC_FRAME_SIZE)) == NULL) {
printk(KERN_ERR "EtherCAT: Could not allocate device tx socket buffer!\n");
return -1;
}
if ((ecd->rx_skb = dev_alloc_skb(EC_FRAME_SIZE)) == NULL) {
dev_kfree_skb(ecd->tx_skb);
ecd->tx_skb = NULL;
printk(KERN_ERR "EtherCAT: Could not allocate device rx socket buffer!\n");
return -1;
}
return 0;
}
/*****************************************************************************/
@ -55,8 +68,10 @@ void EtherCAT_device_init(EtherCAT_device_t *ecd)
@param ecd EtherCAT-Gerät
*/
void EtherCAT_device_clear(EtherCAT_device_t *ecd)
void ec_device_clear(ec_device_t *ecd)
{
if (ecd->open) ec_device_close(ecd);
ecd->dev = NULL;
if (ecd->tx_skb) {
@ -72,50 +87,6 @@ void EtherCAT_device_clear(EtherCAT_device_t *ecd)
/*****************************************************************************/
/**
Weist einem EtherCAT-Gerät das entsprechende net_device zu.
Prüft das net_device, allokiert Socket-Buffer in Sende- und
Empfangsrichtung und weist dem EtherCAT-Gerät und den
Socket-Buffern das net_device zu.
@param ecd EtherCAT-Device
@param dev net_device
@return 0: Erfolg, < 0: Konnte Socket-Buffer nicht allozieren.
*/
int EtherCAT_device_assign(EtherCAT_device_t *ecd,
struct net_device *dev)
{
if (!dev) {
printk("EtherCAT: Device is NULL!\n");
return -1;
}
if ((ecd->tx_skb = dev_alloc_skb(ECAT_FRAME_BUFFER_SIZE)) == NULL) {
printk(KERN_ERR "EtherCAT: Could not allocate device tx socket buffer!\n");
return -1;
}
if ((ecd->rx_skb = dev_alloc_skb(ECAT_FRAME_BUFFER_SIZE)) == NULL) {
dev_kfree_skb(ecd->tx_skb);
ecd->tx_skb = NULL;
printk(KERN_ERR "EtherCAT: Could not allocate device rx socket buffer!\n");
return -1;
}
ecd->dev = dev;
ecd->tx_skb->dev = dev;
ecd->rx_skb->dev = dev;
printk("EtherCAT: Assigned Device %X.\n", (unsigned) dev);
return 0;
}
/*****************************************************************************/
/**
Führt die open()-Funktion des Netzwerktreibers aus.
@ -129,7 +100,7 @@ int EtherCAT_device_assign(EtherCAT_device_t *ecd,
fehlgeschlagen
*/
int EtherCAT_device_open(EtherCAT_device_t *ecd)
int ec_device_open(ec_device_t *ecd)
{
unsigned int i;
@ -143,15 +114,22 @@ int EtherCAT_device_open(EtherCAT_device_t *ecd)
return -1;
}
// Device could have received frames before
for (i = 0; i < 4; i++) EtherCAT_device_call_isr(ecd);
if (ecd->open) {
printk(KERN_WARNING "EtherCAT: Device already opened!\n");
}
else {
// Device could have received frames before
for (i = 0; i < 4; i++) ec_device_call_isr(ecd);
// Reset old device state
ecd->state = ECAT_DS_READY;
ecd->tx_intr_cnt = 0;
ecd->rx_intr_cnt = 0;
// Reset old device state
ecd->state = EC_DEVICE_STATE_READY;
ecd->tx_intr_cnt = 0;
ecd->rx_intr_cnt = 0;
return ecd->dev->open(ecd->dev);
if (ecd->dev->open(ecd->dev) == 0) ecd->open = 1;
}
return ecd->open ? 0 : -1;
}
/*****************************************************************************/
@ -161,21 +139,28 @@ int EtherCAT_device_open(EtherCAT_device_t *ecd)
@param ecd EtherCAT-Gerät
@return 0 bei Erfolg, < 0: Kein Gerät zum Schliessen
@return 0 bei Erfolg, < 0: Kein Gerät zum Schliessen oder
Schliessen fehlgeschlagen.
*/
int EtherCAT_device_close(EtherCAT_device_t *ecd)
int ec_device_close(ec_device_t *ecd)
{
if (!ecd->dev) {
printk("EtherCAT: No device to close!\n");
printk(KERN_ERR "EtherCAT: No device to close!\n");
return -1;
}
printk("EtherCAT: Stopping device (txcnt: %u, rxcnt: %u)\n",
(unsigned int) ecd->tx_intr_cnt,
(unsigned int) ecd->rx_intr_cnt);
if (!ecd->open) {
printk(KERN_WARNING "EtherCAT: Device already closed!\n");
}
else {
printk(KERN_INFO "EtherCAT: Stopping device (txcnt: %u, rxcnt: %u)\n",
(unsigned int) ecd->tx_intr_cnt, (unsigned int) ecd->rx_intr_cnt);
return ecd->dev->stop(ecd->dev);
if (ecd->dev->stop(ecd->dev) == 0) ecd->open = 0;
}
return !ecd->open ? 0 : -1;
}
/*****************************************************************************/
@ -195,16 +180,14 @@ int EtherCAT_device_close(EtherCAT_device_t *ecd)
nicht empfangen, oder kein Speicher mehr vorhanden
*/
int EtherCAT_device_send(EtherCAT_device_t *ecd,
unsigned char *data,
unsigned int length)
int ec_device_send(ec_device_t *ecd, unsigned char *data, unsigned int length)
{
unsigned char *frame_data;
struct ethhdr *eth;
if (unlikely(ecd->state == ECAT_DS_SENT)) {
printk(KERN_WARNING "EtherCAT: Warning - Trying to send frame"
" while last was not received!\n");
if (unlikely(ecd->state == EC_DEVICE_STATE_SENT)) {
printk(KERN_WARNING "EtherCAT: Warning - Trying to send frame while last "
" was not received!\n");
}
// Clear transmit socket buffer and reserve
@ -234,7 +217,7 @@ int EtherCAT_device_send(EtherCAT_device_t *ecd,
rdtscl(ecd->tx_time); // Get CPU cycles
// Start sending of frame
ecd->state = ECAT_DS_SENT;
ecd->state = EC_DEVICE_STATE_SENT;
ecd->dev->hard_start_xmit(ecd->tx_skb, ecd->dev);
return 0;
@ -256,10 +239,9 @@ int EtherCAT_device_send(EtherCAT_device_t *ecd,
@return Anzahl der kopierten Bytes bei Erfolg, sonst < 0
*/
int EtherCAT_device_receive(EtherCAT_device_t *ecd,
unsigned char *data)
int ec_device_receive(ec_device_t *ecd, unsigned char *data)
{
if (unlikely(ecd->state != ECAT_DS_RECEIVED)) {
if (unlikely(ecd->state != EC_DEVICE_STATE_RECEIVED)) {
if (likely(ecd->error_reported)) {
printk(KERN_ERR "EtherCAT: receive - Nothing received!\n");
ecd->error_reported = 1;
@ -267,7 +249,7 @@ int EtherCAT_device_receive(EtherCAT_device_t *ecd,
return -1;
}
if (unlikely(ecd->rx_data_length > ECAT_FRAME_BUFFER_SIZE)) {
if (unlikely(ecd->rx_data_length > EC_FRAME_SIZE)) {
if (likely(ecd->error_reported)) {
printk(KERN_ERR "EtherCAT: receive - "
" Reveived frame is too long (%i Bytes)!\n",
@ -296,7 +278,7 @@ int EtherCAT_device_receive(EtherCAT_device_t *ecd,
@return Anzahl der kopierten Bytes bei Erfolg, sonst < 0
*/
void EtherCAT_device_call_isr(EtherCAT_device_t *ecd)
void ec_device_call_isr(ec_device_t *ecd)
{
if (likely(ecd->isr)) ecd->isr(0, ecd->dev, NULL);
}
@ -309,7 +291,7 @@ void EtherCAT_device_call_isr(EtherCAT_device_t *ecd)
@param ecd EtherCAT-Gerät
*/
void EtherCAT_device_debug(EtherCAT_device_t *ecd)
void ec_device_debug(ec_device_t *ecd)
{
printk(KERN_DEBUG "---EtherCAT device information begin---\n");
@ -336,7 +318,7 @@ void EtherCAT_device_debug(EtherCAT_device_t *ecd)
printk(KERN_DEBUG "Receive buffer: %X\n",
(unsigned) ecd->rx_data);
printk(KERN_DEBUG "Receive buffer fill state: %u/%u\n",
(unsigned) ecd->rx_data_length, ECAT_FRAME_BUFFER_SIZE);
(unsigned) ecd->rx_data_length, EC_FRAME_SIZE);
}
else
{
@ -346,13 +328,51 @@ void EtherCAT_device_debug(EtherCAT_device_t *ecd)
printk(KERN_DEBUG "---EtherCAT device information end---\n");
}
/******************************************************************************
*
* Treiberschnittstelle
*
*****************************************************************************/
void EtherCAT_dev_state(ec_device_t *ecd, ec_device_state_t state)
{
if (state == EC_DEVICE_STATE_TIMEOUT && ecd->state != EC_DEVICE_STATE_SENT) {
printk(KERN_WARNING "EtherCAT: Wrong status at timeout: %i\n", ecd->state);
}
ecd->state = state;
}
/*****************************************************************************/
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);
int EtherCAT_dev_is_ec(ec_device_t *ecd, struct net_device *dev)
{
return ecd->dev == dev;
}
/*****************************************************************************/
int EtherCAT_dev_receive(ec_device_t *ecd, void *data, unsigned int size)
{
if (ecd->state != EC_DEVICE_STATE_SENT)
{
printk(KERN_WARNING "EtherCAT: Received frame while not in SENT state!\n");
return -1;
}
// Copy received data to ethercat-device buffer, skip Ethernet-II header
memcpy(ecd->rx_data, data, size);
ecd->rx_data_length = size;
ecd->state = EC_DEVICE_STATE_RECEIVED;
return 0;
}
/*****************************************************************************/
EXPORT_SYMBOL(EtherCAT_dev_is_ec);
EXPORT_SYMBOL(EtherCAT_dev_state);
EXPORT_SYMBOL(EtherCAT_dev_receive);
/*****************************************************************************/

View File

@ -1,6 +1,6 @@
/******************************************************************************
*
* e c _ d e v i c e . h
* d e v i c e . h
*
* Struktur für ein EtherCAT-Gerät.
*
@ -13,29 +13,8 @@
#include <linux/interrupt.h>
#include "ec_globals.h"
/*****************************************************************************/
/**
Zustand eines EtherCAT-Gerätes.
Eine Für EtherCAT reservierte Netzwerkkarte kann bestimmte Zustände haben.
*/
typedef enum
{
ECAT_DS_READY, /**< Das Gerät ist bereit zum Senden */
ECAT_DS_SENT, /**< Das Gerät hat einen Rahmen abgesendet,
aber noch keine Antwort enpfangen */
ECAT_DS_RECEIVED, /**< Das Gerät hat eine Antwort auf einen
zuvor gesendeten Rahmen empfangen */
ECAT_DS_TIMEOUT, /**< Nach dem Senden eines Rahmens meldete
das Gerät einen Timeout */
ECAT_DS_ERROR /**< Nach dem Senden eines frames hat das
Gerät einen Fehler festgestellt. */
}
EtherCAT_device_state_t;
#include "globals.h"
#include "../include/EtherCAT_dev.h"
/*****************************************************************************/
@ -47,9 +26,10 @@ EtherCAT_device_state_t;
und zu empfangen.
*/
typedef struct
struct ec_device
{
struct net_device *dev; /**< Zeiger auf das reservierte net_device */
unsigned int open; /**< Das net_device ist geoeffnet. */
struct sk_buff *tx_skb; /**< Zeiger auf Transmit-Socketbuffer */
struct sk_buff *rx_skb; /**< Zeiger auf Receive-Socketbuffer */
unsigned long tx_time; /**< Zeit des letzten Sendens */
@ -57,10 +37,10 @@ typedef struct
unsigned long tx_intr_cnt; /**< Anzahl Tx-Interrupts */
unsigned long rx_intr_cnt; /**< Anzahl Rx-Interrupts */
unsigned long intr_cnt; /**< Anzahl Interrupts */
volatile EtherCAT_device_state_t state; /**< Gesendet, Empfangen,
Timeout, etc. */
unsigned char rx_data[ECAT_FRAME_BUFFER_SIZE]; /**< Puffer für
empfangene Rahmen */
volatile ec_device_state_t state; /**< Gesendet, Empfangen,
Timeout, etc. */
unsigned char rx_data[EC_FRAME_SIZE]; /**< Puffer für
empfangene Rahmen */
volatile unsigned int rx_data_length; /**< Länge des zuletzt
empfangenen Rahmens */
irqreturn_t (*isr)(int, void *, struct pt_regs *); /**< Adresse der ISR */
@ -68,23 +48,17 @@ typedef struct
Verfügung stellt. */
int error_reported; /**< Zeigt an, ob ein Fehler im zyklischen Code
bereits gemeldet wurde. */
}
EtherCAT_device_t;
};
/*****************************************************************************/
void EtherCAT_device_init(EtherCAT_device_t *);
int EtherCAT_device_assign(EtherCAT_device_t *, struct net_device *);
void EtherCAT_device_clear(EtherCAT_device_t *);
int EtherCAT_device_open(EtherCAT_device_t *);
int EtherCAT_device_close(EtherCAT_device_t *);
int EtherCAT_device_send(EtherCAT_device_t *, unsigned char *, unsigned int);
int EtherCAT_device_receive(EtherCAT_device_t *, unsigned char *);
void EtherCAT_device_call_isr(EtherCAT_device_t *);
void EtherCAT_device_debug(EtherCAT_device_t *);
int ec_device_init(ec_device_t *);
void ec_device_clear(ec_device_t *);
int ec_device_open(ec_device_t *);
int ec_device_close(ec_device_t *);
void ec_device_call_isr(ec_device_t *);
int ec_device_send(ec_device_t *, unsigned char *, unsigned int);
int ec_device_receive(ec_device_t *, unsigned char *);
/*****************************************************************************/

View File

@ -1,6 +1,6 @@
/******************************************************************************
*
* e c _ d o m a i n . c
* d o m a i n . c
*
* Methoden für Gruppen von EtherCAT-Slaves.
*
@ -10,8 +10,8 @@
#include <linux/module.h>
#include "ec_globals.h"
#include "ec_domain.h"
#include "globals.h"
#include "domain.h"
/*****************************************************************************/
@ -21,14 +21,14 @@
@param pd Zeiger auf die zu initialisierende Domäne
*/
void EtherCAT_domain_init(EtherCAT_domain_t *dom)
void ec_domain_init(ec_domain_t *dom)
{
dom->number = 0;
dom->data_size = 0;
dom->logical_offset = 0;
dom->response_count = 0;
memset(dom->data, 0x00, ECAT_FRAME_BUFFER_SIZE);
memset(dom->data, 0x00, EC_FRAME_SIZE);
}
/*****************************************************************************/

View File

@ -1,6 +1,6 @@
/******************************************************************************
*
* e c _ d o m a i n . h
* d o m a i n . h
*
* Struktur für eine Gruppe von EtherCAT-Slaves.
*
@ -11,9 +11,9 @@
#ifndef _EC_DOMAIN_H_
#define _EC_DOMAIN_H_
#include "ec_globals.h"
#include "ec_slave.h"
#include "ec_command.h"
#include "globals.h"
#include "slave.h"
#include "command.h"
/*****************************************************************************/
@ -24,21 +24,21 @@
Menge von Slaves.
*/
typedef struct EtherCAT_domain
typedef struct ec_domain
{
unsigned int number; /*<< Domänen-Identifikation */
EtherCAT_command_t command; /**< Kommando zum Senden und Empfangen der
Prozessdaten */
unsigned char data[ECAT_FRAME_BUFFER_SIZE]; /**< Prozessdaten-Array */
ec_command_t command; /**< Kommando zum Senden und Empfangen der
Prozessdaten */
unsigned char data[EC_FRAME_SIZE]; /**< Prozessdaten-Array */
unsigned int data_size; /**< Größe der Prozessdaten */
unsigned int logical_offset; /**< Logische Basisaddresse */
unsigned int response_count; /**< Anzahl antwortender Slaves */
}
EtherCAT_domain_t;
ec_domain_t;
/*****************************************************************************/
void EtherCAT_domain_init(EtherCAT_domain_t *);
void ec_domain_init(ec_domain_t *);
/*****************************************************************************/

77
master/globals.h Normal file
View File

@ -0,0 +1,77 @@
/******************************************************************************
*
* g l o b a l s . h
*
* Globale Definitionen und Makros für das EtherCAT-Protokoll.
*
* $Id$
*
*****************************************************************************/
#ifndef _EC_GLOBALS_
#define _EC_GLOBALS_
/*****************************************************************************/
/**
Maximale Größe eines EtherCAT-Frames
*/
#define EC_FRAME_SIZE 1500
/**
Maximale Anzahl der Prozessdatendomänen in einem Master
*/
#define EC_MAX_DOMAINS 10
/**
NULL-Define, falls noch nicht definiert.
*/
#ifndef NULL
#define NULL ((void *) 0)
#endif
/*****************************************************************************/
/**
EtherCAT-Kommando-Typ
*/
typedef enum
{
EC_COMMAND_NONE = 0x00, /**< Dummy */
EC_COMMAND_APRD = 0x01, /**< Auto-increment physical read */
EC_COMMAND_APWR = 0x02, /**< Auto-increment physical write */
EC_COMMAND_NPRD = 0x04, /**< Node-addressed physical read */
EC_COMMAND_NPWR = 0x05, /**< Node-addressed physical write */
EC_COMMAND_BRD = 0x07, /**< Broadcast read */
EC_COMMAND_BWR = 0x08, /**< Broadcast write */
EC_COMMAND_LRW = 0x0C /**< Logical read/write */
}
ec_command_type_t;
/*****************************************************************************/
/**
Zustand eines EtherCAT-Slaves
*/
typedef enum
{
EC_SLAVE_STATE_UNKNOWN = 0x00, /**< Status unbekannt */
EC_SLAVE_STATE_INIT = 0x01, /**< Init-Zustand (Keine Mailbox-
Kommunikation, Kein I/O) */
EC_SLAVE_STATE_PREOP = 0x02, /**< Pre-Operational (Mailbox-
Kommunikation, Kein I/O) */
EC_SLAVE_STATE_SAVEOP = 0x04, /**< Save-Operational (Mailbox-
Kommunikation und Input Update) */
EC_SLAVE_STATE_OP = 0x08, /**< Operational, (Mailbox-
Kommunikation und Input/Output Update) */
EC_ACK = 0x10 /**< Acknoledge-Bit beim Zustandswechsel
(dies ist kein eigener Zustand) */
}
ec_slave_state_t;
/*****************************************************************************/
#endif

File diff suppressed because it is too large Load Diff

75
master/master.h Normal file
View File

@ -0,0 +1,75 @@
/******************************************************************************
*
* m a s t e r . h
*
* Struktur für einen EtherCAT-Master.
*
* $Id$
*
*****************************************************************************/
#ifndef _EC_MASTER_H_
#define _EC_MASTER_H_
#include "device.h"
#include "slave.h"
#include "command.h"
#include "domain.h"
/*****************************************************************************/
/**
EtherCAT-Master
Verwaltet die EtherCAT-Slaves und kommuniziert mit
dem zugewiesenen EtherCAT-Gerät.
*/
typedef struct ec_master
{
ec_slave_t *bus_slaves; /**< Array von Slaves auf dem Bus */
unsigned int bus_slaves_count; /**< Anzahl Slaves auf dem Bus */
ec_device_t device; /**< EtherCAT-Gerät */
unsigned int device_registered; /**< Ein Geraet hat sich registriert. */
unsigned char command_index; /**< Aktueller Kommando-Index */
unsigned char tx_data[EC_FRAME_SIZE]; /**< Statischer Speicher
für zu sendende Daten */
unsigned int tx_data_length; /**< Länge der Daten im Sendespeicher */
unsigned char rx_data[EC_FRAME_SIZE]; /**< Statische Speicher für
eine Kopie des Rx-Buffers
im EtherCAT-Gerät */
unsigned int rx_data_length; /**< Länge der Daten im Empfangsspeicher */
ec_domain_t domains[EC_MAX_DOMAINS]; /** Prozessdatendomänen */
unsigned int domain_count;
int debug_level; /**< Debug-Level im Master-Code */
unsigned int bus_time; /**< Letzte Bus-Zeit in Mikrosekunden */
unsigned int frames_lost; /**< Anzahl verlorene Frames */
unsigned long t_lost_output; /*<< Timer-Ticks bei der letzten Ausgabe von
verlorenen Frames */
}
ec_master_t;
/*****************************************************************************/
// Private Methods
// Master creation and deletion
void ec_master_init(ec_master_t *);
void ec_master_clear(ec_master_t *);
// Registration of devices
int ec_master_open(ec_master_t *);
void ec_master_close(ec_master_t *);
// Slave management
int ec_scan_for_slaves(ec_master_t *);
/*****************************************************************************/
#endif
/* Emacs-Konfiguration
;;; Local Variables: ***
;;; c-basic-offset:2 ***
;;; End: ***
*/

View File

@ -1,6 +1,6 @@
/******************************************************************************
*
* ec_module.c
* m o d u l e . c
*
* EtherCAT-Master-Treiber
*
@ -22,10 +22,13 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include "ec_module.h"
#include "master.h"
#include "device.h"
int __init ecat_init_module(void);
void __exit ecat_cleanup_module(void);
/*****************************************************************************/
int __init ec_init_module(void);
void __exit ec_cleanup_module(void);
/*****************************************************************************/
@ -38,9 +41,9 @@ void __exit ecat_cleanup_module(void);
/*****************************************************************************/
int ecat_master_count = 1;
EtherCAT_master_t *ecat_masters = NULL;
int *ecat_masters_reserved = NULL;
int ec_master_count = 1;
ec_master_t *ec_masters = NULL;
int *ec_masters_reserved = NULL;
/*****************************************************************************/
@ -50,67 +53,58 @@ MODULE_DESCRIPTION ("EtherCAT master driver module");
MODULE_LICENSE("GPL");
MODULE_VERSION(COMPILE_INFO);
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_register_device);
EXPORT_SYMBOL(EtherCAT_unregister_device);
EXPORT_SYMBOL(EtherCAT_request);
EXPORT_SYMBOL(EtherCAT_release);
module_param(ec_master_count, int, 1);
MODULE_PARM_DESC(ec_master_count, "Number of EtherCAT master to initialize.");
/*****************************************************************************/
/**
Init-Funktion des EtherCAT-Master-Treibermodules
Initialisiert soviele Master, wie im Parameter ecat_master_count
Initialisiert soviele Master, wie im Parameter ec_master_count
angegeben wurde (Default ist 1).
@returns 0, wenn alles o.k., -1 bei ungueltiger Anzahl Master
oder zu wenig Speicher.
oder zu wenig Speicher.
*/
int __init ecat_init_module(void)
int __init ec_init_module(void)
{
unsigned int i;
printk(KERN_ERR "EtherCAT: Master driver, %s\n", COMPILE_INFO);
if (ecat_master_count < 1) {
if (ec_master_count < 1) {
printk(KERN_ERR "EtherCAT: Error - Illegal"
" ecat_master_count: %i\n", ecat_master_count);
" ec_master_count: %i\n", ec_master_count);
return -1;
}
printk(KERN_ERR "EtherCAT: Initializing %i EtherCAT master(s)...\n",
ecat_master_count);
ec_master_count);
if ((ecat_masters =
(EtherCAT_master_t *) kmalloc(sizeof(EtherCAT_master_t)
* ecat_master_count,
GFP_KERNEL)) == NULL) {
if ((ec_masters =
(ec_master_t *) kmalloc(sizeof(ec_master_t)
* ec_master_count,
GFP_KERNEL)) == NULL) {
printk(KERN_ERR "EtherCAT: Could not allocate"
" memory for EtherCAT master(s)!\n");
return -1;
}
if ((ecat_masters_reserved =
(int *) kmalloc(sizeof(int) * ecat_master_count,
if ((ec_masters_reserved =
(int *) kmalloc(sizeof(int) * ec_master_count,
GFP_KERNEL)) == NULL) {
printk(KERN_ERR "EtherCAT: Could not allocate"
" memory for reservation flags!\n");
kfree(ecat_masters);
kfree(ec_masters);
return -1;
}
for (i = 0; i < ecat_master_count; i++)
for (i = 0; i < ec_master_count; i++)
{
EtherCAT_master_init(&ecat_masters[i]);
ecat_masters_reserved[i] = 0;
ec_master_init(&ec_masters[i]);
ec_masters_reserved[i] = 0;
}
printk(KERN_ERR "EtherCAT: Master driver initialized.\n");
@ -126,52 +120,84 @@ int __init ecat_init_module(void)
Entfernt alle Master-Instanzen.
*/
void __exit ecat_cleanup_module(void)
void __exit ec_cleanup_module(void)
{
unsigned int i;
printk(KERN_ERR "EtherCAT: Cleaning up master driver...\n");
if (ecat_masters)
if (ec_masters)
{
for (i = 0; i < ecat_master_count; i++)
for (i = 0; i < ec_master_count; i++)
{
if (ecat_masters_reserved[i]) {
if (ec_masters_reserved[i]) {
printk(KERN_WARNING "EtherCAT: Warning -"
" Master %i is still in use!\n", i);
}
EtherCAT_master_clear(&ecat_masters[i]);
ec_master_clear(&ec_masters[i]);
}
kfree(ecat_masters);
kfree(ec_masters);
}
printk(KERN_ERR "EtherCAT: Master driver cleaned up.\n");
}
/*****************************************************************************/
/******************************************************************************
*
* Treiberschnittstelle
*
*****************************************************************************/
/**
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.
< 0, wenn bereits ein Geraet registriert
oder das Geraet nicht geoeffnet werden konnte.
*/
int EtherCAT_register_device(int index, EtherCAT_device_t *device)
ec_device_t *EtherCAT_dev_register(unsigned int master_index,
struct net_device *dev,
irqreturn_t (*isr)(int, void *,
struct pt_regs *),
struct module *module)
{
if (index < 0 || index >= ecat_master_count) {
printk(KERN_ERR "EtherCAT: Master %i does not exist!\n", index);
return -1;
ec_device_t *ecd;
if (master_index >= ec_master_count) {
printk(KERN_ERR "EtherCAT: Master %i does not exist!\n", master_index);
return NULL;
}
return EtherCAT_master_open(&ecat_masters[index], device);
if (!dev) {
printk("EtherCAT: Device is NULL!\n");
return NULL;
}
if (ec_masters[master_index].device_registered) {
printk(KERN_ERR "EtherCAT: Master %i already has a device!\n",
master_index);
return NULL;
}
ecd = &ec_masters[master_index].device;
if (ec_device_init(ecd) < 0) {
return NULL;
}
ecd->dev = dev;
ecd->tx_skb->dev = dev;
ecd->rx_skb->dev = dev;
ecd->isr = isr;
ecd->module = module;
return ecd;
}
/*****************************************************************************/
@ -183,17 +209,22 @@ int EtherCAT_register_device(int index, EtherCAT_device_t *device)
@param device Das EtherCAT-Geraet
*/
void EtherCAT_unregister_device(int index, EtherCAT_device_t *device)
void EtherCAT_dev_unregister(unsigned int master_index)
{
if (index < 0 || index >= ecat_master_count) {
printk(KERN_WARNING "EtherCAT: Master %i does not exist!\n", index);
if (master_index >= ec_master_count) {
printk(KERN_WARNING "EtherCAT: Master %i does not exist!\n", master_index);
return;
}
EtherCAT_master_close(&ecat_masters[index], device);
ec_masters[master_index].device_registered = 0;
ec_device_clear(&ec_masters[master_index].device);
}
/*****************************************************************************/
/******************************************************************************
*
* Echtzeitschnittstelle
*
*****************************************************************************/
/**
Reserviert einen bestimmten EtherCAT-Master und das zugehörige Gerät.
@ -204,44 +235,56 @@ void EtherCAT_unregister_device(int index, EtherCAT_device_t *device)
@returns Zeiger auf EtherCAT-Master oder NULL, wenn Parameter ungueltig.
*/
EtherCAT_master_t *EtherCAT_request(int index)
ec_master_t *EtherCAT_rt_request_master(int index)
{
if (index < 0 || index >= ecat_master_count) {
ec_master_t *master;
if (index < 0 || index >= ec_master_count) {
printk(KERN_ERR "EtherCAT: Master %i does not exist!\n", index);
return NULL;
goto req_return;
}
if (ecat_masters_reserved[index]) {
if (ec_masters_reserved[index]) {
printk(KERN_ERR "EtherCAT: Master %i already in use!\n", index);
return NULL;
goto req_return;
}
if (!ecat_masters[index].dev) {
master = &ec_masters[index];
if (!master->device_registered) {
printk(KERN_ERR "EtherCAT: Master %i has no device assigned yet!\n",
index);
return NULL;
goto req_return;
}
if (!ecat_masters[index].dev->module) {
printk(KERN_ERR "EtherCAT: Master %i device module is not set!\n", index);
return NULL;
}
if (!try_module_get(ecat_masters[index].dev->module)) {
if (!try_module_get(master->device.module)) {
printk(KERN_ERR "EtherCAT: Could not reserve device module!\n");
return NULL;
goto req_return;
}
if (EtherCAT_scan_for_slaves(&ecat_masters[index]) != 0) {
printk(KERN_ERR "EtherCAT: Could not scan for slaves!\n");
return NULL;
if (ec_master_open(master) < 0) {
printk(KERN_ERR "EtherCAT: Could not open device!\n");
goto req_module_put;
}
ecat_masters_reserved[index] = 1;
if (ec_scan_for_slaves(master) != 0) {
printk(KERN_ERR "EtherCAT: Could not scan for slaves!\n");
goto req_close;
}
ec_masters_reserved[index] = 1;
printk(KERN_INFO "EtherCAT: Reserved master %i.\n", index);
return &ecat_masters[index];
return master;
req_close:
ec_master_close(master);
req_module_put:
module_put(master->device.module);
req_return:
return NULL;
}
/*****************************************************************************/
@ -252,22 +295,23 @@ EtherCAT_master_t *EtherCAT_request(int index)
@param master Zeiger auf den freizugebenden EtherCAT-Master.
*/
void EtherCAT_release(EtherCAT_master_t *master)
void EtherCAT_rt_release_master(ec_master_t *master)
{
unsigned int i;
for (i = 0; i < ecat_master_count; i++)
for (i = 0; i < ec_master_count; i++)
{
if (&ecat_masters[i] == master)
if (&ec_masters[i] == master)
{
if (!ecat_masters[i].dev) {
if (!master->device_registered) {
printk(KERN_WARNING "EtherCAT: Could not release device"
"module because of no device!\n");
return;
}
module_put(ecat_masters[i].dev->module);
ecat_masters_reserved[i] = 0;
ec_master_close(master);
module_put(master->device.module);
ec_masters_reserved[i] = 0;
printk(KERN_INFO "EtherCAT: Released master %i.\n", i);
@ -280,3 +324,13 @@ void EtherCAT_release(EtherCAT_master_t *master)
}
/*****************************************************************************/
module_init(ec_init_module);
module_exit(ec_cleanup_module);
EXPORT_SYMBOL(EtherCAT_dev_register);
EXPORT_SYMBOL(EtherCAT_dev_unregister);
EXPORT_SYMBOL(EtherCAT_rt_request_master);
EXPORT_SYMBOL(EtherCAT_rt_release_master);
/*****************************************************************************/

View File

@ -1,6 +1,6 @@
/******************************************************************************
*
* e c _ s l a v e . c
* s l a v e . c
*
* Methoden für einen EtherCAT-Slave.
*
@ -10,8 +10,8 @@
#include <linux/module.h>
#include "ec_globals.h"
#include "ec_slave.h"
#include "globals.h"
#include "slave.h"
/*****************************************************************************/
@ -26,7 +26,7 @@
@param slave Zeiger auf den zu initialisierenden Slave
*/
void EtherCAT_slave_init(EtherCAT_slave_t *slave)
void ec_slave_init(ec_slave_t *slave)
{
slave->type = 0;
slave->revision = 0;
@ -39,8 +39,8 @@ void EtherCAT_slave_init(EtherCAT_slave_t *slave)
slave->serial_number = 0;
slave->desc = NULL;
slave->logical_address = 0;
slave->current_state = ECAT_STATE_UNKNOWN;
slave->requested_state = ECAT_STATE_UNKNOWN;
slave->current_state = EC_SLAVE_STATE_UNKNOWN;
slave->requested_state = EC_SLAVE_STATE_UNKNOWN;
slave->process_data = NULL;
slave->domain = 0;
slave->error_reported = 0;
@ -48,6 +48,7 @@ void EtherCAT_slave_init(EtherCAT_slave_t *slave)
/*****************************************************************************/
#if 0
/**
Liest einen bestimmten Kanal des Slaves als Integer-Wert.
@ -188,6 +189,7 @@ void EtherCAT_write_value(EtherCAT_slave_t *slave,
EXPORT_SYMBOL(EtherCAT_write_value);
EXPORT_SYMBOL(EtherCAT_read_value);
#endif
/*****************************************************************************/

View File

@ -1,6 +1,6 @@
/******************************************************************************
*
* e c _ s l a v e . h
* s l a v e . h
*
* Struktur für einen EtherCAT-Slave.
*
@ -11,7 +11,7 @@
#ifndef _EC_SLAVE_H_
#define _EC_SLAVE_H_
#include "ec_types.h"
#include "types.h"
/*****************************************************************************/
@ -39,32 +39,34 @@ typedef struct
unsigned int revision_number; /**< Revisionsnummer */
unsigned int serial_number; /**< Seriennummer der Klemme */
const EtherCAT_slave_desc_t *desc; /**< Zeiger auf die Beschreibung
const ec_slave_desc_t *desc; /**< Zeiger auf die Beschreibung
des Slave-Typs */
unsigned int logical_address; /**< Konfigurierte, logische adresse */
EtherCAT_state_t current_state; /**< Aktueller Zustand */
EtherCAT_state_t requested_state; /**< Angeforderter Zustand */
ec_slave_state_t current_state; /**< Aktueller Zustand */
ec_slave_state_t requested_state; /**< Angeforderter Zustand */
unsigned char *process_data; /**< Zeiger auf den Speicherbereich
innerhalb eines Prozessdatenobjekts */
unsigned int domain; /**< Prozessdatendomäne */
int error_reported; /**< Ein Zugriffsfehler wurde bereits gemeldet */
}
EtherCAT_slave_t;
ec_slave_t;
#define ECAT_INIT_SLAVE(TYPE, DOMAIN) {0, 0, 0, 0, 0, 0, 0, 0, 0, \
#define EC_INIT_SLAVE(TYPE, DOMAIN) {0, 0, 0, 0, 0, 0, 0, 0, 0, \
TYPE, 0, ECAT_STATE_UNKNOWN, \
ECAT_STATE_UNKNOWN, NULL, DOMAIN, 0}
EC_STATE_UNKNOWN, NULL, DOMAIN, 0}
/*****************************************************************************/
// Slave construction and deletion
void EtherCAT_slave_init(EtherCAT_slave_t *);
void ec_slave_init(ec_slave_t *);
#if 0
int EtherCAT_read_value(EtherCAT_slave_t *, unsigned int);
void EtherCAT_write_value(EtherCAT_slave_t *, unsigned int, int);
#endif
/*****************************************************************************/

View File

@ -1,6 +1,6 @@
/******************************************************************************
*
* e c _ t y p e s . c
* t y p e s . c
*
* EtherCAT-Slave-Typen.
*
@ -10,8 +10,8 @@
#include <linux/module.h>
#include "ec_globals.h"
#include "ec_types.h"
#include "globals.h"
#include "types.h"
/*****************************************************************************/
@ -54,12 +54,10 @@ int read_1014(unsigned char *data, unsigned int channel)
void write_2004(unsigned char *data, unsigned int channel, int value)
{
if (value)
{
if (value) {
data[0] |= (1 << channel);
}
else
{
else {
data[0] &= ~(1 << channel);
}
}
@ -79,80 +77,80 @@ void write_41xx(unsigned char *data, unsigned int channel, int value)
/* Klemmen-Objekte */
EtherCAT_slave_desc_t Beckhoff_EK1100[] =
ec_slave_desc_t Beckhoff_EK1100[] =
{{
"Beckhoff", "EK1100", "Bus Coupler",
ECAT_ST_SIMPLE_NOSYNC,
EC_NOSYNC_SLAVE,
NULL, NULL, NULL, NULL,
NULL,
0, 0,
NULL, NULL
}};
EtherCAT_slave_desc_t Beckhoff_EL1014[] =
ec_slave_desc_t Beckhoff_EL1014[] =
{{
"Beckhoff", "EL1014", "4x Digital Input",
ECAT_ST_SIMPLE,
EC_SIMPLE_SLAVE,
sm0_1014, NULL, NULL, NULL,
fmmu0_1014,
1, 4,
read_1014, NULL
}};
EtherCAT_slave_desc_t Beckhoff_EL2004[] =
ec_slave_desc_t Beckhoff_EL2004[] =
{{
"Beckhoff", "EL2004", "4x Digital Output",
ECAT_ST_SIMPLE,
EC_SIMPLE_SLAVE,
sm0_2004, NULL, NULL, NULL,
fmmu0_2004,
1, 4,
NULL, write_2004
}};
EtherCAT_slave_desc_t Beckhoff_EL3102[] =
ec_slave_desc_t Beckhoff_EL3102[] =
{{
"Beckhoff", "EL3102", "2x Analog Input diff.",
ECAT_ST_MAILBOX,
EC_MAILBOX_SLAVE,
sm0_multi, sm1_multi, sm2_31xx, sm3_31xx,
fmmu0_31xx,
6, 2,
read_31xx, NULL
}};
EtherCAT_slave_desc_t Beckhoff_EL3162[] =
ec_slave_desc_t Beckhoff_EL3162[] =
{{
"Beckhoff", "EL3162", "2x Analog Input",
ECAT_ST_MAILBOX,
EC_MAILBOX_SLAVE,
sm0_multi, sm1_multi, sm2_31xx, sm3_31xx,
fmmu0_31xx,
6, 2,
read_31xx, NULL
}};
EtherCAT_slave_desc_t Beckhoff_EL4102[] =
ec_slave_desc_t Beckhoff_EL4102[] =
{{
"Beckhoff", "EL4102", "2x Analog Output",
ECAT_ST_MAILBOX,
EC_MAILBOX_SLAVE,
sm0_multi, sm1_multi, sm2_41xx, NULL,
fmmu0_41xx,
4, 2,
NULL, write_41xx
}};
EtherCAT_slave_desc_t Beckhoff_EL4132[] =
ec_slave_desc_t Beckhoff_EL4132[] =
{{
"Beckhoff", "EL4132", "2x Analog Output diff.",
ECAT_ST_MAILBOX,
EC_MAILBOX_SLAVE,
sm0_multi, sm1_multi, sm2_41xx, NULL,
fmmu0_41xx,
4, 2,
NULL, write_41xx
}};
EtherCAT_slave_desc_t Beckhoff_EL5001[] =
ec_slave_desc_t Beckhoff_EL5001[] =
{{
"Beckhoff", "EL5001", "SSI-Interface",
ECAT_ST_SIMPLE,
EC_SIMPLE_SLAVE,
NULL, NULL, NULL, NULL, // Noch nicht eingepflegt...
NULL,
0, 0,
@ -169,7 +167,7 @@ EtherCAT_slave_desc_t Beckhoff_EL5001[] =
Neue Klemmen müssen hier eingetragen werden.
*/
EtherCAT_slave_ident_t slave_idents[] =
ec_slave_ident_t slave_idents[] =
{
{0x00000002, 0x03F63052, Beckhoff_EL1014},
{0x00000002, 0x044C2C52, Beckhoff_EK1100},
@ -182,18 +180,7 @@ EtherCAT_slave_ident_t slave_idents[] =
};
unsigned int slave_ident_count = sizeof(slave_idents)
/ sizeof(EtherCAT_slave_ident_t);
/ sizeof(ec_slave_ident_t);
/*****************************************************************************/
EXPORT_SYMBOL(Beckhoff_EK1100);
EXPORT_SYMBOL(Beckhoff_EL1014);
EXPORT_SYMBOL(Beckhoff_EL2004);
EXPORT_SYMBOL(Beckhoff_EL3102);
EXPORT_SYMBOL(Beckhoff_EL3162);
EXPORT_SYMBOL(Beckhoff_EL4102);
EXPORT_SYMBOL(Beckhoff_EL4132);
EXPORT_SYMBOL(Beckhoff_EL5001);
/*****************************************************************************/

View File

@ -1,6 +1,6 @@
/******************************************************************************
*
* e c _ t y p e s . h
* t y p e s . h
*
* EtherCAT-Slave-Typen.
*
@ -23,9 +23,9 @@
typedef enum
{
ECAT_ST_SIMPLE, ECAT_ST_MAILBOX, ECAT_ST_SIMPLE_NOSYNC
EC_SIMPLE_SLAVE, EC_MAILBOX_SLAVE, EC_NOSYNC_SLAVE
}
EtherCAT_slave_type_t;
ec_slave_type_t;
/*****************************************************************************/
@ -43,7 +43,7 @@ typedef struct slave_desc
const char *product_name; /**< Name des Slaves-Typs */
const char *product_desc; /**< Genauere Beschreibung des Slave-Typs */
const EtherCAT_slave_type_t type; /**< Art des Slave-Typs */
const ec_slave_type_t type; /**< Art des Slave-Typs */
const unsigned char *sm0; /**< Konfigurationsdaten des
ersten Sync-Managers */
@ -66,7 +66,7 @@ typedef struct slave_desc
Kodieren und Schreiben
der Kanaldaten */
}
EtherCAT_slave_desc_t;
ec_slave_desc_t;
/*****************************************************************************/
@ -81,27 +81,16 @@ typedef struct slave_ident
{
const unsigned int vendor_id; /**< Hersteller-Code */
const unsigned int product_code; /**< Herstellerspezifischer Produktcode */
const EtherCAT_slave_desc_t *desc; /**< Zeiger auf den dazugehörigen
const ec_slave_desc_t *desc; /**< Zeiger auf den dazugehörigen
Slave-Typ */
}
EtherCAT_slave_ident_t;
ec_slave_ident_t;
extern EtherCAT_slave_ident_t slave_idents[]; /**< Statisches Array der
Slave-Identifikationen */
extern ec_slave_ident_t slave_idents[]; /**< Statisches Array der
Slave-Identifikationen */
extern unsigned int slave_ident_count; /**< Anzahl der vorhandenen
Slave-Identifikationen */
/*****************************************************************************/
extern EtherCAT_slave_desc_t Beckhoff_EK1100[];
extern EtherCAT_slave_desc_t Beckhoff_EL1014[];
extern EtherCAT_slave_desc_t Beckhoff_EL2004[];
extern EtherCAT_slave_desc_t Beckhoff_EL3102[];
extern EtherCAT_slave_desc_t Beckhoff_EL3162[];
extern EtherCAT_slave_desc_t Beckhoff_EL4102[];
extern EtherCAT_slave_desc_t Beckhoff_EL4132[];
extern EtherCAT_slave_desc_t Beckhoff_EL5001[];
/*****************************************************************************/
#endif

View File

@ -13,9 +13,9 @@ ifneq ($(KERNELRELEASE),)
#----------------------------------------------------------------
# Kbuild-Abschnitt
obj-m := ec_mini_mod.o
obj-m := ec_mini.o
ec_mini_mod-objs := ec_mini.o
ec_mini-objs := mini.o
#----------------------------------------------------------------

View File

@ -1,289 +0,0 @@
/******************************************************************************
*
* ec_mini.c
*
* Minimalmodul für EtherCAT
*
* $Id$
*
*****************************************************************************/
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/timer.h>
#include "../drivers/ec_master.h"
#include "../drivers/ec_device.h"
#include "../drivers/ec_types.h"
#include "../drivers/ec_module.h"
/*****************************************************************************/
// Auskommentieren, wenn keine zyklischen Daten erwuenscht
#define ECAT_CYCLIC_DATA
/*****************************************************************************/
static EtherCAT_master_t *ecat_master = NULL;
static EtherCAT_slave_t ecat_slaves[] =
{
#if 0
// Block 1
ECAT_INIT_SLAVE(Beckhoff_EK1100, 1),
ECAT_INIT_SLAVE(Beckhoff_EL4102, 1),
ECAT_INIT_SLAVE(Beckhoff_EL3162, 1),
ECAT_INIT_SLAVE(Beckhoff_EL1014, 1),
ECAT_INIT_SLAVE(Beckhoff_EL4102, 1),
ECAT_INIT_SLAVE(Beckhoff_EL4102, 1),
ECAT_INIT_SLAVE(Beckhoff_EL4102, 1),
ECAT_INIT_SLAVE(Beckhoff_EL3162, 1),
ECAT_INIT_SLAVE(Beckhoff_EL3162, 1),
ECAT_INIT_SLAVE(Beckhoff_EL3162, 1),
ECAT_INIT_SLAVE(Beckhoff_EL3102, 1),
ECAT_INIT_SLAVE(Beckhoff_EL3102, 1),
ECAT_INIT_SLAVE(Beckhoff_EL3102, 1),
#endif
#if 1
// Block 2
ECAT_INIT_SLAVE(Beckhoff_EK1100, 1),
ECAT_INIT_SLAVE(Beckhoff_EL4102, 1),
ECAT_INIT_SLAVE(Beckhoff_EL1014, 1),
ECAT_INIT_SLAVE(Beckhoff_EL3162, 1),
ECAT_INIT_SLAVE(Beckhoff_EL2004, 1),
ECAT_INIT_SLAVE(Beckhoff_EL3102, 1),
ECAT_INIT_SLAVE(Beckhoff_EL2004, 1),
ECAT_INIT_SLAVE(Beckhoff_EL2004, 1),
ECAT_INIT_SLAVE(Beckhoff_EL2004, 1),
ECAT_INIT_SLAVE(Beckhoff_EL2004, 1),
ECAT_INIT_SLAVE(Beckhoff_EL2004, 1),
// Block 3
ECAT_INIT_SLAVE(Beckhoff_EK1100, 1),
ECAT_INIT_SLAVE(Beckhoff_EL1014, 1),
ECAT_INIT_SLAVE(Beckhoff_EL1014, 1),
ECAT_INIT_SLAVE(Beckhoff_EL1014, 1),
ECAT_INIT_SLAVE(Beckhoff_EL1014, 1),
ECAT_INIT_SLAVE(Beckhoff_EL1014, 1),
ECAT_INIT_SLAVE(Beckhoff_EL2004, 1),
ECAT_INIT_SLAVE(Beckhoff_EL2004, 1),
ECAT_INIT_SLAVE(Beckhoff_EL2004, 1),
ECAT_INIT_SLAVE(Beckhoff_EL2004, 1),
ECAT_INIT_SLAVE(Beckhoff_EL1014, 1),
ECAT_INIT_SLAVE(Beckhoff_EL1014, 1),
ECAT_INIT_SLAVE(Beckhoff_EL1014, 1)
#endif
};
#define ECAT_SLAVES_COUNT (sizeof(ecat_slaves) / sizeof(EtherCAT_slave_t))
#ifdef ECAT_CYCLIC_DATA
int value;
int dig1;
struct timer_list timer;
unsigned long last_start_jiffies;
#endif // ECAT_CYCLIC_DATA
/******************************************************************************
*
* Function: next2004
*
*****************************************************************************/
#ifdef ECAT_CYCLIC_DATA
static int next2004(int *wrap)
{
static int i = 0;
unsigned int j = 0;
*wrap = 0;
for (j = 0; j < ECAT_SLAVES_COUNT; j++)
{
i++;
i %= ECAT_SLAVES_COUNT;
if (i == 0) *wrap = 1;
if (ecat_slaves[i].desc == Beckhoff_EL2004)
{
return i;
}
}
return -1;
}
#endif
/******************************************************************************
*
* Function: run
*
* Beschreibung: Zyklischer Prozess
*
*****************************************************************************/
#ifdef ECAT_CYCLIC_DATA
static void run(unsigned long data)
{
static int ms = 0;
static int cnt = 0;
static unsigned long int k = 0;
static int firstrun = 1;
static int klemme = 0;
static int kanal = 0;
static int up_down = 0;
int wrap = 0;
ms++;
ms %= 1000;
if (firstrun) klemme = next2004(&wrap);
if (cnt++ > 20)
{
cnt = 0;
if (++kanal > 3)
{
kanal = 0;
klemme = next2004(&wrap);
if (wrap == 1)
{
if (up_down == 1) up_down = 0;
else up_down = 1;
}
}
}
if (klemme >= 0)
EtherCAT_write_value(&ecat_slaves[klemme], kanal, up_down);
// Prozessdaten lesen und schreiben
rdtscl(k);
EtherCAT_process_data_cycle(ecat_master, 1, 100);
firstrun = 0;
timer.expires += HZ / 1000;
add_timer(&timer);
}
#endif // ECAT_CYCLIC_DATA
/******************************************************************************
*
* Function: init
*
*****************************************************************************/
int __init init_module()
{
unsigned int i;
printk(KERN_INFO "=== Starting Minimal EtherCAT environment... ===\n");
if ((ecat_master = EtherCAT_request(0)) == NULL) {
printk(KERN_ERR "EtherCAT master 0 not available!\n");
goto out_return;
}
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_release_master;
}
printk("Activating all EtherCAT slaves.\n");
for (i = 0; i < ECAT_SLAVES_COUNT; i++) {
if (EtherCAT_activate_slave(ecat_master, &ecat_slaves[i]) != 0) {
printk(KERN_ERR "EtherCAT: Could not activate slave %i!\n", i);
goto out_release_master;
}
}
#ifdef ECAT_CYCLIC_DATA
printk("Starting cyclic sample thread.\n");
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);
printk("Initialised sample thread.\n");
#endif
printk(KERN_INFO "=== Minimal EtherCAT environment started. ===\n");
return 0;
out_release_master:
EtherCAT_release(ecat_master);
out_return:
return -1;
}
/******************************************************************************
*
* Function: cleanup
*
*****************************************************************************/
void __exit cleanup_module()
{
unsigned int i;
printk(KERN_INFO "=== Stopping Minimal EtherCAT environment... ===\n");
if (ecat_master)
{
#ifdef ECAT_CYCLIC_DATA
del_timer_sync(&timer);
#endif // ECAT_CYCLIC_DATA
printk(KERN_INFO "Deactivating slaves.\n");
for (i = 0; i < ECAT_SLAVES_COUNT; i++) {
EtherCAT_deactivate_slave(ecat_master, &ecat_slaves[i]);
}
EtherCAT_release(ecat_master);
}
printk(KERN_INFO "=== Minimal EtherCAT environment stopped. ===\n");
}
/*****************************************************************************/
MODULE_LICENSE("GPL");
MODULE_AUTHOR ("Florian Pose <fp@igh-essen.com>");
MODULE_DESCRIPTION ("Minimal EtherCAT environment");
module_init(init_module);
module_exit(cleanup_module);
/*****************************************************************************/
/* Emacs-Konfiguration
;;; Local Variables: ***
;;; c-basic-offset:4 ***
;;; End: ***
*/

160
mini/mini.c Normal file
View File

@ -0,0 +1,160 @@
/******************************************************************************
*
* m i n i . c
*
* Minimalmodul für EtherCAT
*
* $Id$
*
*****************************************************************************/
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/timer.h>
#include "../include/EtherCAT_rt.h"
/*****************************************************************************/
// Auskommentieren, wenn keine zyklischen Daten erwuenscht
#define ECAT_CYCLIC_DATA
/*****************************************************************************/
ec_master_t *master = NULL;
#ifdef ECAT_CYCLIC_DATA
int value;
int dig1;
struct timer_list timer;
unsigned long last_start_jiffies;
#endif // ECAT_CYCLIC_DATA
/******************************************************************************
*
* Function: run
*
* Beschreibung: Zyklischer Prozess
*
*****************************************************************************/
#ifdef ECAT_CYCLIC_DATA
static void run(unsigned long data)
{
static int ms = 0;
static unsigned long int k = 0;
static int firstrun = 1;
ms++;
ms %= 1000;
#if 0
if (klemme >= 0)
EtherCAT_write_value(&ecat_slaves[klemme], kanal, up_down);
#endif
// Prozessdaten lesen und schreiben
rdtscl(k);
EtherCAT_rt_domain_cycle(master, 1, 100);
firstrun = 0;
timer.expires += HZ / 1000;
add_timer(&timer);
}
#endif // ECAT_CYCLIC_DATA
/******************************************************************************
*
* Function: init
*
*****************************************************************************/
int __init init_mini_module(void)
{
printk(KERN_INFO "=== Starting Minimal EtherCAT environment... ===\n");
if ((master = EtherCAT_rt_request_master(0)) == NULL) {
printk(KERN_ERR "EtherCAT master 0 not available!\n");
goto out_return;
}
//check_slaves();
printk("Activating all EtherCAT slaves.\n");
if (EtherCAT_rt_activate_slaves(master) != 0) {
printk(KERN_ERR "EtherCAT: Could not activate slaves!\n");
goto out_release_master;
}
#ifdef ECAT_CYCLIC_DATA
printk("Starting cyclic sample thread.\n");
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);
printk("Initialised sample thread.\n");
#endif
printk(KERN_INFO "=== Minimal EtherCAT environment started. ===\n");
return 0;
out_release_master:
EtherCAT_rt_release_master(master);
out_return:
return -1;
}
/******************************************************************************
*
* Function: cleanup
*
*****************************************************************************/
void __exit cleanup_mini_module(void)
{
printk(KERN_INFO "=== Stopping Minimal EtherCAT environment... ===\n");
if (master)
{
#ifdef ECAT_CYCLIC_DATA
del_timer_sync(&timer);
#endif // ECAT_CYCLIC_DATA
printk(KERN_INFO "Deactivating slaves.\n");
EtherCAT_rt_deactivate_slaves(master);
EtherCAT_rt_release_master(master);
}
printk(KERN_INFO "=== Minimal EtherCAT environment stopped. ===\n");
}
/*****************************************************************************/
MODULE_LICENSE("GPL");
MODULE_AUTHOR ("Florian Pose <fp@igh-essen.com>");
MODULE_DESCRIPTION ("Minimal EtherCAT environment");
module_init(init_mini_module);
module_exit(cleanup_mini_module);
/*****************************************************************************/
/* Emacs-Konfiguration
;;; Local Variables: ***
;;; c-basic-offset:4 ***
;;; End: ***
*/

View File

@ -32,10 +32,7 @@
#include "msr_jitter.h"
// EtherCAT
#include "../drivers/ec_master.h"
#include "../drivers/ec_device.h"
#include "../drivers/ec_types.h"
#include "../drivers/ec_module.h"
#include "../include/EtherCAT_rt.h"
// Defines/Makros
#define TSC2US(T1, T2) ((T2 - T1) * 1000UL / cpu_khz)
@ -54,16 +51,18 @@ static struct ipipe_sysinfo sys_info;
// EtherCAT
static EtherCAT_master_t *ecat_master = NULL;
ec_master_t *master = NULL;
static unsigned int ecat_bus_time = 0;
static unsigned int ecat_timeouts = 0;
static EtherCAT_slave_t ecat_slaves[] =
#if 0
static ec_slave_t slaves[] =
{
// Block 1
ECAT_INIT_SLAVE(Beckhoff_EK1100, 0),
ECAT_INIT_SLAVE(Beckhoff_EL3102, 0)
};
#endif
#define ECAT_SLAVES_COUNT (sizeof(ecat_slaves) / sizeof(EtherCAT_slave_t))
@ -87,20 +86,22 @@ static void msr_controller_run(void)
// Prozessdaten lesen
msr_jitter_run(MSR_ABTASTFREQUENZ);
#if 0
if (debug_counter == 0) {
ecat_master->debug_level = 2;
master->debug_level = 2;
}
#endif
// Prozessdaten schreiben
if (EtherCAT_process_data_cycle(ecat_master, 0, 40) < 0)
ecat_timeouts++;
// Prozessdaten lesen und schreiben
EtherCAT_rt_domain_cycle(master, 0, 40);
#if 0
if (debug_counter == 0) {
ecat_master->debug_level = 0;
master->debug_level = 0;
}
#endif
value = EtherCAT_read_value(&ecat_slaves[1], 0);
// value = EtherCAT_read_value(&ecat_slaves[1], 0);
debug_counter++;
if (debug_counter >= MSR_ABTASTFREQUENZ * 5) debug_counter = 0;
@ -183,9 +184,8 @@ int msr_globals_register(void)
* the init/clean material
*****************************************************************************/
int __init init_module()
int __init init_rt_module(void)
{
unsigned int i;
struct ipipe_domain_attr attr; //ipipe
// Als allererstes die RT-lib initialisieren
@ -200,25 +200,24 @@ int __init init_module()
printk(KERN_INFO "=== Starting EtherCAT environment... ===\n");
if ((ecat_master = EtherCAT_request(0)) == NULL) {
if ((master = EtherCAT_rt_request_master(0)) == NULL) {
printk(KERN_ERR "EtherCAT master 0 not available!\n");
goto out_msr_cleanup;
}
#if 0
printk("Checking EtherCAT slaves.\n");
if (EtherCAT_check_slaves(ecat_master, ecat_slaves, ECAT_SLAVES_COUNT) != 0) {
if (EtherCAT_check_slaves(master, ecat_slaves, ECAT_SLAVES_COUNT) != 0) {
printk(KERN_ERR "EtherCAT: Could not init slaves!\n");
goto out_release_master;
}
#endif
printk("Activating all EtherCAT slaves.\n");
for (i = 0; i < ECAT_SLAVES_COUNT; i++) {
if (EtherCAT_activate_slave(ecat_master, ecat_slaves + i) < 0) {
printk(KERN_ERR "EtherCAT: Could not activate slave %i!\n", i);
goto out_release_master;
}
if (EtherCAT_rt_activate_slaves(master) < 0) {
printk(KERN_ERR "EtherCAT: Could not activate slaves!\n");
goto out_release_master;
}
do_gettimeofday(&process_time);
@ -234,7 +233,7 @@ int __init init_module()
return 0;
out_release_master:
EtherCAT_release(ecat_master);
EtherCAT_rt_release_master(master);
out_msr_cleanup:
msr_rtlib_cleanup();
@ -245,28 +244,24 @@ int __init init_module()
/*****************************************************************************/
void __exit cleanup_module()
void __exit cleanup_rt_module(void)
{
unsigned int i;
msr_print_info("msk_modul: unloading...");
ipipe_tune_timer(1000000000UL / HZ, 0); //alten Timertakt wieder herstellen
ipipe_unregister_domain(&this_domain);
if (ecat_master)
if (master)
{
printk(KERN_INFO "=== Stopping EtherCAT environment... ===\n");
printk(KERN_INFO "Deactivating slaves.\n");
for (i = 0; i < ECAT_SLAVES_COUNT; i++) {
if (EtherCAT_deactivate_slave(ecat_master, ecat_slaves + i) < 0) {
printk(KERN_WARNING "Warning - Could not deactivate slave!\n");
}
if (EtherCAT_rt_deactivate_slaves(master) < 0) {
printk(KERN_WARNING "Warning - Could not deactivate slaves!\n");
}
EtherCAT_release(ecat_master);
EtherCAT_rt_release_master(master);
printk(KERN_INFO "=== EtherCAT environment stopped. ===\n");
}
@ -282,7 +277,7 @@ MODULE_LICENSE("GPL");
MODULE_AUTHOR ("Wilhelm Hagemeister <hm@igh-essen.com>");
MODULE_DESCRIPTION ("EtherCAT test environment");
module_init(init_module);
module_exit(cleanup_module);
module_init(init_rt_module);
module_exit(cleanup_rt_module);
/*****************************************************************************/