diff --git a/Makefile b/Makefile index 2b5449f8fd428fdf20301194dab2c88168f3f9a8..8c291f917be2dbeda8e2bd55b917a05f3b5171cf 100644 --- a/Makefile +++ b/Makefile @@ -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." diff --git a/drivers/8139too.c b/devices/8139too.c similarity index 93% rename from drivers/8139too.c rename to devices/8139too.c index a9e94b1f3bbf0d5578a972aa881070ea14509944..5c3e8b775d6be61254129e7242d2b1f2040c1f4f 100644 --- a/drivers/8139too.c +++ b/devices/8139too.c @@ -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); - - if (EtherCAT_device_assign(&rtl_ecat_dev, dev) < 0) - goto err_out; + { + printk(KERN_INFO "Registering EtherCAT device...\n"); + rtl_ec_dev = EtherCAT_dev_register(ec_device_master_index, dev, + rtl8139_interrupt, THIS_MODULE); - 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 <<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ } diff --git a/devices/Makefile b/devices/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..665e1dfccb70fa7d73fcf06922cc472b48ae7ed5 --- /dev/null +++ b/devices/Makefile @@ -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 diff --git a/drivers/original_8139too.c b/devices/original_8139too.c similarity index 100% rename from drivers/original_8139too.c rename to devices/original_8139too.c diff --git a/drivers/EtherCAT.h b/drivers/EtherCAT.h deleted file mode 100644 index 00492b3369d9c3a5b447f20d777710e0cd9db9cf..0000000000000000000000000000000000000000 --- a/drivers/EtherCAT.h +++ /dev/null @@ -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" - -/*****************************************************************************/ - diff --git a/drivers/ec_command.h b/drivers/ec_command.h deleted file mode 100644 index de16689c848aa0d7eaad8a45ca92f9b99d66ef5a..0000000000000000000000000000000000000000 --- a/drivers/ec_command.h +++ /dev/null @@ -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 diff --git a/drivers/ec_globals.h b/drivers/ec_globals.h deleted file mode 100644 index 81c6c43a5af3bd6d65f177c595cd6f3681e5ff61..0000000000000000000000000000000000000000 --- a/drivers/ec_globals.h +++ /dev/null @@ -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 diff --git a/drivers/ec_master.h b/drivers/ec_master.h deleted file mode 100644 index e88647a193807fa9c95e878630e28586bf2d6caf..0000000000000000000000000000000000000000 --- a/drivers/ec_master.h +++ /dev/null @@ -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: *** -*/ diff --git a/drivers/ec_module.h b/drivers/ec_module.h deleted file mode 100644 index 9ebe60f39f72d8f81f483f1a35d30765b059d0ae..0000000000000000000000000000000000000000 --- a/drivers/ec_module.h +++ /dev/null @@ -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 *); - -/*****************************************************************************/ diff --git a/include/EtherCAT_dev.h b/include/EtherCAT_dev.h new file mode 100644 index 0000000000000000000000000000000000000000..1ba87c7f6cc656304f0dbdc90a0a6094b6ca1460 --- /dev/null +++ b/include/EtherCAT_dev.h @@ -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 diff --git a/include/EtherCAT_rt.h b/include/EtherCAT_rt.h new file mode 100644 index 0000000000000000000000000000000000000000..23faff9fb1d419dda002970853baeb34d7a89f9a --- /dev/null +++ b/include/EtherCAT_rt.h @@ -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 diff --git a/drivers/Makefile b/master/Makefile similarity index 84% rename from drivers/Makefile rename to master/Makefile index a3b2ee33793ed1c7b99d0d690b1ee8cc5be6516c..dd7e00e24da2b418d543a455a670a2b8f1f2d8be 100644 --- a/drivers/Makefile +++ b/master/Makefile @@ -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` diff --git a/drivers/ec_command.c b/master/command.c similarity index 65% rename from drivers/ec_command.c rename to master/command.c index f5c2a5a65b56a5e86759ddc97715304f75d64aff..0bd19a302d0c853d928b8e34d7ccae275123d605 100644 --- a/drivers/ec_command.c +++ b/master/command.c @@ -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; } /*****************************************************************************/ diff --git a/master/command.h b/master/command.h new file mode 100644 index 0000000000000000000000000000000000000000..a7ee4edfd76009db4a1a7a0ae1566b7ef6d5f276 --- /dev/null +++ b/master/command.h @@ -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 diff --git a/drivers/ec_device.c b/master/device.c similarity index 70% rename from drivers/ec_device.c rename to master/device.c index 81c223fc36f68a6e1e3ece9e0db335c0095df0eb..07b2a1ee902a5e19d0f4e9ef77264b3c527d57db 100644 --- a/drivers/ec_device.c +++ b/master/device.c @@ -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; + + if (ecd->dev->open(ecd->dev) == 0) ecd->open = 1; + } - return ecd->dev->open(ecd->dev); + 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; +} + +/*****************************************************************************/ + +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_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_dev_is_ec); +EXPORT_SYMBOL(EtherCAT_dev_state); +EXPORT_SYMBOL(EtherCAT_dev_receive); /*****************************************************************************/ diff --git a/drivers/ec_device.h b/master/device.h similarity index 50% rename from drivers/ec_device.h rename to master/device.h index 2ea30767addd66d10c70f3e1156bd332bc816884..fd57a17093d74558845f0226c9c213bfb65a5b90 100644 --- a/drivers/ec_device.h +++ b/master/device.h @@ -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 *); /*****************************************************************************/ diff --git a/drivers/ec_domain.c b/master/domain.c similarity index 80% rename from drivers/ec_domain.c rename to master/domain.c index 13d52c73ffec050cc3ccc29008d733e7420a9bbc..7307c9731d168fa0fdc742958a012e8e1f8679bf 100644 --- a/drivers/ec_domain.c +++ b/master/domain.c @@ -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); } /*****************************************************************************/ diff --git a/drivers/ec_domain.h b/master/domain.h similarity index 71% rename from drivers/ec_domain.h rename to master/domain.h index d89206ab0d13df6aa7ee73409f63a0e3a554641e..091230975606396959c9a16b846cc9e00f519ae2 100644 --- a/drivers/ec_domain.h +++ b/master/domain.h @@ -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 *); /*****************************************************************************/ diff --git a/master/globals.h b/master/globals.h new file mode 100644 index 0000000000000000000000000000000000000000..ed1c5e8a780473caa3f9994b0361cb8abff1fd5a --- /dev/null +++ b/master/globals.h @@ -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 diff --git a/drivers/ec_master.c b/master/master.c similarity index 60% rename from drivers/ec_master.c rename to master/master.c index d6ce83f104b513d8dcd4cd31084098e28e0750e8..4a011037e958c5488f739141d406c1c70721eaf6 100644 --- a/drivers/ec_master.c +++ b/master/master.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * e c _ m a s t e r . c + * m a s t e r . c * * Methoden für einen EtherCAT-Master. * @@ -14,8 +14,21 @@ #include <linux/slab.h> #include <linux/delay.h> -#include "ec_globals.h" -#include "ec_master.h" +#include "globals.h" +#include "master.h" +#include "device.h" +#include "command.h" + +/*****************************************************************************/ + +// Prototypen + +int ec_simple_send(ec_master_t *, ec_command_t *); +int ec_simple_receive(ec_master_t *, ec_command_t *); +void ec_output_debug_data(const ec_master_t *); +int ec_read_slave_information(ec_master_t *, unsigned short, unsigned short, + unsigned int *); +void ec_output_lost_frames(ec_master_t *); /*****************************************************************************/ @@ -25,11 +38,11 @@ @param master Zeiger auf den zu initialisierenden EtherCAT-Master */ -void EtherCAT_master_init(EtherCAT_master_t *master) +void ec_master_init(ec_master_t *master) { master->bus_slaves = NULL; master->bus_slaves_count = 0; - master->dev = NULL; + master->device_registered = 0; master->command_index = 0x00; master->tx_data_length = 0; master->rx_data_length = 0; @@ -51,51 +64,41 @@ void EtherCAT_master_init(EtherCAT_master_t *master) @param master Zeiger auf den zu löschenden Master */ -void EtherCAT_master_clear(EtherCAT_master_t *master) +void ec_master_clear(ec_master_t *master) { if (master->bus_slaves) { kfree(master->bus_slaves); master->bus_slaves = NULL; } + ec_device_clear(&master->device); + master->domain_count = 0; } /*****************************************************************************/ /** - Öffnet ein EtherCAT-Geraet für den Master. - - Registriert das Geraet beim Master, der es daraufhin oeffnet. + Öffnet das EtherCAT-Geraet des Masters. @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. + + @return 0, wenn alles o.k., < 0, wenn das Geraet nicht geoeffnet werden + konnte. */ -int EtherCAT_master_open(EtherCAT_master_t *master, - EtherCAT_device_t *device) +int ec_master_open(ec_master_t *master) { - if (!master || !device) { - printk(KERN_ERR "EtherCAT: Illegal parameters for master_open()!\n"); - return -1; - } - - if (master->dev) { - printk(KERN_ERR "EtherCAT: Master already has a device.\n"); + if (!master->device_registered) { + printk(KERN_ERR "EtherCAT: No device registered!\n"); return -1; } - if (EtherCAT_device_open(device) < 0) { - printk(KERN_ERR "EtherCAT: Could not open device %X!\n", - (unsigned int) master->dev); + if (ec_device_open(&master->device) < 0) { + printk(KERN_ERR "EtherCAT: Could not open device!\n"); return -1; } - master->dev = device; - return 0; } @@ -108,21 +111,17 @@ int EtherCAT_master_open(EtherCAT_master_t *master, @param device Das EtherCAT-Geraet */ -void EtherCAT_master_close(EtherCAT_master_t *master, - EtherCAT_device_t *device) +void ec_master_close(ec_master_t *master) { - if (master->dev != device) { + if (!master->device_registered) { printk(KERN_WARNING "EtherCAT: Warning -" - " Trying to close an unknown device!\n"); + " Trying to close an unregistered device!\n"); return; } - if (EtherCAT_device_close(master->dev) < 0) { - printk(KERN_WARNING "EtherCAT: Warning -" - " Could not close device!\n"); + if (ec_device_close(&master->device) < 0) { + printk(KERN_WARNING "EtherCAT: Warning - Could not close device!\n"); } - - master->dev = NULL; } /*****************************************************************************/ @@ -137,27 +136,24 @@ void EtherCAT_master_close(EtherCAT_master_t *master, @return 0 bei Erfolg, sonst < 0 */ -int EtherCAT_simple_send_receive(EtherCAT_master_t *master, - EtherCAT_command_t *cmd) +int ec_simple_send_receive(ec_master_t *master, ec_command_t *cmd) { unsigned int tries_left; - if (unlikely(EtherCAT_simple_send(master, cmd) < 0)) + if (unlikely(ec_simple_send(master, cmd) < 0)) return -1; - udelay(3); - - EtherCAT_device_call_isr(master->dev); - tries_left = 20; - while (unlikely(master->dev->state == ECAT_DS_SENT - && tries_left)) { + + do + { udelay(1); - EtherCAT_device_call_isr(master->dev); + ec_device_call_isr(&master->device); tries_left--; } + while (unlikely(master->device.state == EC_DEVICE_STATE_SENT && tries_left)); - if (unlikely(EtherCAT_simple_receive(master, cmd) < 0)) + if (unlikely(ec_simple_receive(master, cmd) < 0)) return -1; return 0; @@ -174,24 +170,22 @@ int EtherCAT_simple_send_receive(EtherCAT_master_t *master, @return 0 bei Erfolg, sonst < 0 */ -int EtherCAT_simple_send(EtherCAT_master_t *master, - EtherCAT_command_t *cmd) +int ec_simple_send(ec_master_t *master, ec_command_t *cmd) { unsigned int length, framelength, i; if (unlikely(master->debug_level > 0)) { - printk(KERN_DEBUG "EtherCAT_send_receive_command\n"); + printk(KERN_DEBUG "EtherCAT: ec_simple_send\n"); } - if (unlikely(cmd->state != ECAT_CS_READY)) { - printk(KERN_WARNING "EtherCAT_send_receive_command:" - "Command not in ready state!\n"); + if (unlikely(cmd->state != EC_COMMAND_STATE_READY)) { + printk(KERN_WARNING "EtherCAT: cmd not in ready state!\n"); } length = cmd->data_length + 12; framelength = length + 2; - if (unlikely(framelength > ECAT_FRAME_BUFFER_SIZE)) { + if (unlikely(framelength > EC_FRAME_SIZE)) { printk(KERN_ERR "EtherCAT: Frame too long (%i)!\n", framelength); return -1; } @@ -199,7 +193,7 @@ int EtherCAT_simple_send(EtherCAT_master_t *master, if (framelength < 46) framelength = 46; if (unlikely(master->debug_level > 0)) { - printk(KERN_DEBUG "Frame length: %i\n", framelength); + printk(KERN_DEBUG "EtherCAT: Frame length: %i\n", framelength); } master->tx_data[0] = length & 0xFF; @@ -209,10 +203,10 @@ int EtherCAT_simple_send(EtherCAT_master_t *master, master->command_index = (master->command_index + 1) % 0x0100; if (unlikely(master->debug_level > 0)) { - printk(KERN_DEBUG "Sending command index %i\n", cmd->index); + printk(KERN_DEBUG "EtherCAT: Sending command index %i\n", cmd->index); } - cmd->state = ECAT_CS_SENT; + cmd->state = EC_COMMAND_STATE_SENT; master->tx_data[2 + 0] = cmd->type; master->tx_data[2 + 1] = cmd->index; @@ -225,10 +219,10 @@ int EtherCAT_simple_send(EtherCAT_master_t *master, master->tx_data[2 + 8] = 0x00; master->tx_data[2 + 9] = 0x00; - if (likely(cmd->type == ECAT_CMD_APWR - || cmd->type == ECAT_CMD_NPWR - || cmd->type == ECAT_CMD_BWR - || cmd->type == ECAT_CMD_LRW)) // Write commands + if (likely(cmd->type == EC_COMMAND_APWR + || cmd->type == EC_COMMAND_NPWR + || cmd->type == EC_COMMAND_BWR + || cmd->type == EC_COMMAND_LRW)) // Write commands { for (i = 0; i < cmd->data_length; i++) master->tx_data[2 + 10 + i] = cmd->data[i]; @@ -247,19 +241,18 @@ int EtherCAT_simple_send(EtherCAT_master_t *master, master->tx_data_length = framelength; if (unlikely(master->debug_level > 0)) { - printk(KERN_DEBUG "device send...\n"); + printk(KERN_DEBUG "EtherCAT: Device send...\n"); } // Send frame - if (unlikely(EtherCAT_device_send(master->dev, - master->tx_data, - framelength) != 0)) { + if (unlikely(ec_device_send(&master->device, master->tx_data, + framelength) != 0)) { printk(KERN_ERR "EtherCAT: Could not send!\n"); return -1; } if (unlikely(master->debug_level > 0)) { - printk(KERN_DEBUG "EtherCAT_send done.\n"); + printk(KERN_DEBUG "EtherCAT: ec_simple_send done.\n"); } return 0; @@ -277,15 +270,13 @@ int EtherCAT_simple_send(EtherCAT_master_t *master, @return 0 bei Erfolg, sonst < 0 */ -int EtherCAT_simple_receive(EtherCAT_master_t *master, - EtherCAT_command_t *cmd) +int ec_simple_receive(ec_master_t *master, ec_command_t *cmd) { unsigned int length; int ret; unsigned char command_type, command_index; - if (unlikely((ret = EtherCAT_device_receive(master->dev, - master->rx_data)) < 0)) + if (unlikely((ret = ec_device_receive(&master->device, master->rx_data)) < 0)) return -1; master->rx_data_length = (unsigned int) ret; @@ -293,7 +284,7 @@ int EtherCAT_simple_receive(EtherCAT_master_t *master, if (unlikely(master->rx_data_length < 2)) { printk(KERN_ERR "EtherCAT: Received frame with incomplete EtherCAT" " header!\n"); - output_debug_data(master); + ec_output_debug_data(master); return -1; } @@ -304,7 +295,7 @@ int EtherCAT_simple_receive(EtherCAT_master_t *master, if (unlikely(length > master->rx_data_length)) { printk(KERN_ERR "EtherCAT: Received corrupted frame (length does" " not match)!\n"); - output_debug_data(master); + ec_output_debug_data(master); return -1; } @@ -316,16 +307,16 @@ int EtherCAT_simple_receive(EtherCAT_master_t *master, if (unlikely(master->rx_data_length - 2 < length + 12)) { printk(KERN_ERR "EtherCAT: Received frame with" " incomplete command data!\n"); - output_debug_data(master); + ec_output_debug_data(master); return -1; } - if (likely(cmd->state == ECAT_CS_SENT + if (likely(cmd->state == EC_COMMAND_STATE_SENT && cmd->type == command_type && cmd->index == command_index && cmd->data_length == length)) { - cmd->state = ECAT_CS_RECEIVED; + cmd->state = EC_COMMAND_STATE_RECEIVED; // Empfangene Daten in Kommandodatenspeicher kopieren memcpy(cmd->data, master->rx_data + 2 + 10, length); @@ -336,16 +327,16 @@ int EtherCAT_simple_receive(EtherCAT_master_t *master, | ((master->rx_data[length + 2 + 11] & 0xFF) << 8)); if (unlikely(master->debug_level > 1)) { - output_debug_data(master); + ec_output_debug_data(master); } } else { printk(KERN_WARNING "EtherCAT: WARNING - Send/Receive anomaly!\n"); - output_debug_data(master); + ec_output_debug_data(master); } - master->dev->state = ECAT_DS_READY; + master->device.state = EC_DEVICE_STATE_READY; return 0; } @@ -360,18 +351,18 @@ int EtherCAT_simple_receive(EtherCAT_master_t *master, @return 0 bei Erfolg, sonst < 0 */ -int EtherCAT_scan_for_slaves(EtherCAT_master_t *master) +int ec_scan_for_slaves(ec_master_t *master) { - EtherCAT_command_t cmd; - EtherCAT_slave_t *cur; + ec_command_t cmd; + ec_slave_t *cur; unsigned int i, j; unsigned char data[2]; // Determine number of slaves on bus - EtherCAT_command_broadcast_read(&cmd, 0x0000, 4); + ec_command_broadcast_read(&cmd, 0x0000, 4); - if (unlikely(EtherCAT_simple_send_receive(master, &cmd) < 0)) + if (unlikely(ec_simple_send_receive(master, &cmd) < 0)) return -1; master->bus_slaves_count = cmd.working_counter; @@ -379,9 +370,9 @@ int EtherCAT_scan_for_slaves(EtherCAT_master_t *master) if (!master->bus_slaves_count) return 0; - if (!(master->bus_slaves = - (EtherCAT_slave_t *) kmalloc(master->bus_slaves_count * - sizeof(EtherCAT_slave_t), GFP_KERNEL))) { + if (!(master->bus_slaves = (ec_slave_t *) kmalloc(master->bus_slaves_count + * sizeof(ec_slave_t), + GFP_KERNEL))) { printk(KERN_ERR "EtherCAT: Could not allocate memory for bus slaves!\n"); return -1; } @@ -391,13 +382,13 @@ int EtherCAT_scan_for_slaves(EtherCAT_master_t *master) { cur = master->bus_slaves + i; - EtherCAT_slave_init(cur); + ec_slave_init(cur); // Read base data - EtherCAT_command_read(&cmd, cur->station_address, 0x0000, 4); + ec_command_read(&cmd, cur->station_address, 0x0000, 4); - if (unlikely(EtherCAT_simple_send_receive(master, &cmd) < 0)) + if (unlikely(ec_simple_send_receive(master, &cmd) < 0)) return -1; if (unlikely(cmd.working_counter != 1)) { @@ -414,38 +405,28 @@ int EtherCAT_scan_for_slaves(EtherCAT_master_t *master) // Read identification from "Slave Information Interface" (SII) - if (unlikely(EtherCAT_read_slave_information(master, - cur->station_address, - 0x0008, - &cur->vendor_id) != 0)) - { + if (unlikely(ec_read_slave_information(master, cur->station_address, + 0x0008, &cur->vendor_id) != 0)) { printk(KERN_ERR "EtherCAT: Could not read SII vendor id!\n"); return -1; } - if (unlikely(EtherCAT_read_slave_information(master, - cur->station_address, - 0x000A, - &cur->product_code) != 0)) - { + if (unlikely(ec_read_slave_information(master, cur->station_address, + 0x000A, &cur->product_code) != 0)) { printk(KERN_ERR "EtherCAT: Could not read SII product code!\n"); return -1; } - if (unlikely(EtherCAT_read_slave_information(master, - cur->station_address, - 0x000C, - &cur->revision_number) != 0)) - { + if (unlikely(ec_read_slave_information(master, cur->station_address, + 0x000C, + &cur->revision_number) != 0)) { printk(KERN_ERR "EtherCAT: Could not read SII revision number!\n"); return -1; } - if (unlikely(EtherCAT_read_slave_information(master, - cur->station_address, - 0x000E, - &cur->serial_number) != 0)) - { + if (unlikely(ec_read_slave_information(master, cur->station_address, + 0x000E, + &cur->serial_number) != 0)) { printk(KERN_ERR "EtherCAT: Could not read SII serial number!\n"); return -1; } @@ -477,10 +458,9 @@ int EtherCAT_scan_for_slaves(EtherCAT_master_t *master) data[0] = cur->station_address & 0x00FF; data[1] = (cur->station_address & 0xFF00) >> 8; - EtherCAT_command_position_write(&cmd, cur->ring_position, - 0x0010, 2, data); + ec_command_position_write(&cmd, cur->ring_position, 0x0010, 2, data); - if (unlikely(EtherCAT_simple_send_receive(master, &cmd) < 0)) + if (unlikely(ec_simple_send_receive(master, &cmd) < 0)) return -1; if (unlikely(cmd.working_counter != 1)) { @@ -495,83 +475,6 @@ int EtherCAT_scan_for_slaves(EtherCAT_master_t *master) /*****************************************************************************/ -/** - Registriert einen Slave beim Master. - - @param master Der EtherCAT-Master - - @return 0 bei Erfolg, sonst < 0 -*/ - -void *EtherCAT_register_slave(EtherCAT_master_t *master, - unsigned int bus_index, - const char *vendor_name, - const char *product_name, - unsigned int domain) -{ - EtherCAT_slave_t *slave; - EtherCAT_domain_t *dom; - unsigned int j; - - if (bus_index >= master->bus_slaves_count) { - printk(KERN_ERR "EtherCAT: Illegal bus index! (%i / %i)\n", bus_index, - master->bus_slaves_count); - return NULL; - } - - slave = master->bus_slaves + bus_index; - - if (slave->process_data) { - printk(KERN_ERR "EtherCAT: Slave %i is already registered!\n", bus_index); - return NULL; - } - - if (strcmp(vendor_name, slave->desc->vendor_name) || - strcmp(product_name, slave->desc->product_name)) { - printk(KERN_ERR "Invalid Slave Type! Requested: \"%s %s\", present: \"%s" - "%s\".\n", vendor_name, product_name, slave->desc->vendor_name, - slave->desc->product_name); - return NULL; - } - - // Check, if process data domain already exists... - dom = NULL; - for (j = 0; j < master->domain_count; j++) { - if (domain == master->domains[j].number) { - dom = master->domains + j; - } - } - - // Create process data domain - if (!dom) { - if (master->domain_count > ECAT_MAX_DOMAINS - 1) { - printk(KERN_ERR "EtherCAT: Too many domains!\n"); - return NULL; - } - - dom = master->domains + master->domain_count; - EtherCAT_domain_init(dom); - dom->number = domain; - dom->logical_offset = master->domain_count * ECAT_FRAME_BUFFER_SIZE; - master->domain_count++; - } - - if (dom->data_size + slave->desc->process_data_size - > ECAT_FRAME_BUFFER_SIZE - 14) { - printk(KERN_ERR "EtherCAT: Oversized domain %i: %i / %i Bytes!\n", - dom->number, dom->data_size + slave->desc->process_data_size, - ECAT_FRAME_BUFFER_SIZE - 14); - return NULL; - } - - slave->process_data = dom->data + dom->data_size; - dom->data_size += slave->desc->process_data_size; - - return slave->process_data; -} - -/*****************************************************************************/ - /** Liest Daten aus dem Slave-Information-Interface eines EtherCAT-Slaves. @@ -585,12 +488,12 @@ void *EtherCAT_register_slave(EtherCAT_master_t *master, @return 0 bei Erfolg, sonst < 0 */ -int EtherCAT_read_slave_information(EtherCAT_master_t *master, - unsigned short int node_address, - unsigned short int offset, - unsigned int *target) +int ec_read_slave_information(ec_master_t *master, + unsigned short int node_address, + unsigned short int offset, + unsigned int *target) { - EtherCAT_command_t cmd; + ec_command_t cmd; unsigned char data[10]; unsigned int tries_left; @@ -603,9 +506,9 @@ int EtherCAT_read_slave_information(EtherCAT_master_t *master, data[4] = 0x00; data[5] = 0x00; - EtherCAT_command_write(&cmd, node_address, 0x502, 6, data); + ec_command_write(&cmd, node_address, 0x502, 6, data); - if (unlikely(EtherCAT_simple_send_receive(master, &cmd) < 0)) + if (unlikely(ec_simple_send_receive(master, &cmd) < 0)) return -1; if (unlikely(cmd.working_counter != 1)) { @@ -623,9 +526,9 @@ int EtherCAT_read_slave_information(EtherCAT_master_t *master, { udelay(10); - EtherCAT_command_read(&cmd, node_address, 0x502, 10); + ec_command_read(&cmd, node_address, 0x502, 10); - if (unlikely(EtherCAT_simple_send_receive(master, &cmd) != 0)) + if (unlikely(ec_simple_send_receive(master, &cmd) != 0)) return -1; if (unlikely(cmd.working_counter != 1)) { @@ -666,21 +569,19 @@ int EtherCAT_read_slave_information(EtherCAT_master_t *master, @return 0 bei Erfolg, sonst < 0 */ -int EtherCAT_state_change(EtherCAT_master_t *master, - EtherCAT_slave_t *slave, - unsigned char state_and_ack) +int ec_state_change(ec_master_t *master, ec_slave_t *slave, + unsigned char state_and_ack) { - EtherCAT_command_t cmd; + ec_command_t cmd; unsigned char data[2]; unsigned int tries_left; data[0] = state_and_ack; data[1] = 0x00; - EtherCAT_command_write(&cmd, slave->station_address, - 0x0120, 2, data); + ec_command_write(&cmd, slave->station_address, 0x0120, 2, data); - if (unlikely(EtherCAT_simple_send_receive(master, &cmd) != 0)) { + if (unlikely(ec_simple_send_receive(master, &cmd) != 0)) { printk(KERN_ERR "EtherCAT: Could not set state %02X - Unable to send!\n", state_and_ack); return -1; @@ -700,9 +601,9 @@ int EtherCAT_state_change(EtherCAT_master_t *master, { udelay(10); - EtherCAT_command_read(&cmd, slave->station_address, 0x0130, 2); + ec_command_read(&cmd, slave->station_address, 0x0130, 2); - if (unlikely(EtherCAT_simple_send_receive(master, &cmd) != 0)) { + if (unlikely(ec_simple_send_receive(master, &cmd) != 0)) { printk(KERN_ERR "EtherCAT: Could not check state %02X - Unable to" " send!\n", state_and_ack); return -1; @@ -742,205 +643,345 @@ int EtherCAT_state_change(EtherCAT_master_t *master, /*****************************************************************************/ /** - Konfiguriert einen Slave und setzt den Operational-Zustand. + Gibt Frame-Inhalte zwecks Debugging aus. - Führt eine komplette Konfiguration eines Slaves durch, - setzt Sync-Manager und FMMU's, führt die entsprechenden - Zustandsübergänge durch, bis der Slave betriebsbereit ist. + @param master EtherCAT-Master +*/ + +void ec_output_debug_data(const ec_master_t *master) +{ + unsigned int i; + + printk(KERN_DEBUG "EtherCAT: tx_data content (%i Bytes):\n", + master->tx_data_length); + + printk(KERN_DEBUG); + for (i = 0; i < master->tx_data_length; i++) + { + printk("%02X ", master->tx_data[i]); + if ((i + 1) % 16 == 0) printk("\n" KERN_DEBUG); + } + printk("\n"); + + printk(KERN_DEBUG "EtherCAT: rx_data content (%i Bytes):\n", + master->rx_data_length); + + printk(KERN_DEBUG); + for (i = 0; i < master->rx_data_length; i++) + { + printk("%02X ", master->rx_data[i]); + if ((i + 1) % 16 == 0) printk("\n" KERN_DEBUG); + } + printk("\n"); +} + +/*****************************************************************************/ + +/** + Gibt von Zeit zu Zeit die Anzahl verlorener Frames aus. @param master EtherCAT-Master - @param slave Zu aktivierender Slave +*/ + +void ec_output_lost_frames(ec_master_t *master) +{ + unsigned long int t; + + if (master->frames_lost) { + rdtscl(t); + if ((t - master->t_lost_output) / cpu_khz > 1000) { + printk(KERN_ERR "EtherCAT: %u frame(s) LOST!\n", master->frames_lost); + master->frames_lost = 0; + master->t_lost_output = t; + } + } +} + +/****************************************************************************** + * + * Echtzeitschnittstelle + * + *****************************************************************************/ + +/** + Registriert einen Slave beim Master. + + @param master Der EtherCAT-Master @return 0 bei Erfolg, sonst < 0 */ -int EtherCAT_activate_slave(EtherCAT_master_t *master, - EtherCAT_slave_t *slave) +void *EtherCAT_rt_register_slave(ec_master_t *master, unsigned int bus_index, + const char *vendor_name, + const char *product_name, unsigned int domain) { - EtherCAT_command_t cmd; - const EtherCAT_slave_desc_t *desc; - unsigned char fmmu[16]; - unsigned char data[256]; + ec_slave_t *slave; + ec_domain_t *dom; + unsigned int j; - desc = slave->desc; + if (bus_index >= master->bus_slaves_count) { + printk(KERN_ERR "EtherCAT: Illegal bus index! (%i / %i)\n", bus_index, + master->bus_slaves_count); + return NULL; + } - if (unlikely(EtherCAT_state_change(master, slave, ECAT_STATE_INIT) != 0)) - return -1; + slave = master->bus_slaves + bus_index; - // Resetting FMMU's + if (slave->process_data) { + printk(KERN_ERR "EtherCAT: Slave %i is already registered!\n", bus_index); + return NULL; + } - memset(data, 0x00, 256); + if (strcmp(vendor_name, slave->desc->vendor_name) || + strcmp(product_name, slave->desc->product_name)) { + printk(KERN_ERR "Invalid Slave Type! Requested: \"%s %s\", present: \"%s" + "%s\".\n", vendor_name, product_name, slave->desc->vendor_name, + slave->desc->product_name); + return NULL; + } - EtherCAT_command_write(&cmd, slave->station_address, 0x0600, 256, data); + // Check, if process data domain already exists... + dom = NULL; + for (j = 0; j < master->domain_count; j++) { + if (domain == master->domains[j].number) { + dom = master->domains + j; + } + } - if (unlikely(EtherCAT_simple_send_receive(master, &cmd) < 0)) - return -1; + // Create process data domain + if (!dom) { + if (master->domain_count > EC_MAX_DOMAINS - 1) { + printk(KERN_ERR "EtherCAT: Too many domains!\n"); + return NULL; + } - if (unlikely(cmd.working_counter != 1)) { - printk(KERN_ERR "EtherCAT: Resetting FMMUs - Slave %04X did not" - " respond!\n", slave->station_address); - return -1; + dom = master->domains + master->domain_count; + ec_domain_init(dom); + dom->number = domain; + dom->logical_offset = master->domain_count * EC_FRAME_SIZE; + master->domain_count++; } - // Resetting Sync Manager channels + if (dom->data_size + slave->desc->process_data_size > EC_FRAME_SIZE - 14) { + printk(KERN_ERR "EtherCAT: Oversized domain %i: %i / %i Bytes!\n", + dom->number, dom->data_size + slave->desc->process_data_size, + EC_FRAME_SIZE - 14); + return NULL; + } + + slave->process_data = dom->data + dom->data_size; + dom->data_size += slave->desc->process_data_size; + + return slave->process_data; +} + +/*****************************************************************************/ + +/** + Konfiguriert einen Slave und setzt den Operational-Zustand. + + Führt eine komplette Konfiguration eines Slaves durch, + setzt Sync-Manager und FMMU's, führt die entsprechenden + Zustandsübergänge durch, bis der Slave betriebsbereit ist. + + @param master EtherCAT-Master + @param slave Zu aktivierender Slave - if (desc->type != ECAT_ST_SIMPLE_NOSYNC) + @return 0 bei Erfolg, sonst < 0 +*/ + +int EtherCAT_rt_activate_slaves(ec_master_t *master) +{ + unsigned int i; + ec_slave_t *slave; + ec_command_t cmd; + const ec_slave_desc_t *desc; + unsigned char fmmu[16]; + unsigned char data[256]; + + for (i = 0; i < master->bus_slaves_count; i++) { + slave = master->bus_slaves + i; + desc = slave->desc; + + if (unlikely(ec_state_change(master, slave, EC_SLAVE_STATE_INIT) != 0)) + return -1; + + // Resetting FMMU's + memset(data, 0x00, 256); - EtherCAT_command_write(&cmd, slave->station_address, 0x0800, 256, data); + ec_command_write(&cmd, slave->station_address, 0x0600, 256, data); - if (unlikely(EtherCAT_simple_send_receive(master, &cmd) < 0)) + if (unlikely(ec_simple_send_receive(master, &cmd) < 0)) return -1; if (unlikely(cmd.working_counter != 1)) { - printk(KERN_ERR "EtherCAT: Resetting SMs - Slave %04X did not" + printk(KERN_ERR "EtherCAT: Resetting FMMUs - Slave %04X did not" " respond!\n", slave->station_address); return -1; } - } - // Init Mailbox communication + // Resetting Sync Manager channels - if (desc->type == ECAT_ST_MAILBOX) - { - if (desc->sm0) + if (desc->type != EC_NOSYNC_SLAVE) { - EtherCAT_command_write(&cmd, slave->station_address, 0x0800, 8, - desc->sm0); + memset(data, 0x00, 256); + + ec_command_write(&cmd, slave->station_address, 0x0800, 256, data); - if (unlikely(EtherCAT_simple_send_receive(master, &cmd) < 0)) + if (unlikely(ec_simple_send_receive(master, &cmd) < 0)) return -1; if (unlikely(cmd.working_counter != 1)) { - printk(KERN_ERR "EtherCAT: Setting SM0 - Slave %04X did not" + printk(KERN_ERR "EtherCAT: Resetting SMs - Slave %04X did not" " respond!\n", slave->station_address); return -1; } } - if (desc->sm1) + // Init Mailbox communication + + if (desc->type == EC_MAILBOX_SLAVE) { - EtherCAT_command_write(&cmd, slave->station_address, 0x0808, 8, - desc->sm1); + if (desc->sm0) + { + ec_command_write(&cmd, slave->station_address, 0x0800, 8, + desc->sm0); - if (unlikely(EtherCAT_simple_send_receive(master, &cmd) < 0)) - return -1; + if (unlikely(ec_simple_send_receive(master, &cmd) < 0)) + return -1; - if (unlikely(cmd.working_counter != 1)) { - printk(KERN_ERR "EtherCAT: Setting SM1 -" - " Slave %04X did not respond!\n", - slave->station_address); - return -1; + if (unlikely(cmd.working_counter != 1)) { + printk(KERN_ERR "EtherCAT: Setting SM0 - Slave %04X did not" + " respond!\n", slave->station_address); + return -1; + } + } + + if (desc->sm1) + { + ec_command_write(&cmd, slave->station_address, 0x0808, 8, + desc->sm1); + + if (unlikely(ec_simple_send_receive(master, &cmd) < 0)) + return -1; + + if (unlikely(cmd.working_counter != 1)) { + printk(KERN_ERR "EtherCAT: Setting SM1 -" + " Slave %04X did not respond!\n", + slave->station_address); + return -1; + } } } - } - // Change state to PREOP + // Change state to PREOP - if (unlikely(EtherCAT_state_change(master, slave, ECAT_STATE_PREOP) != 0)) - return -1; + if (unlikely(ec_state_change(master, slave, EC_SLAVE_STATE_PREOP) != 0)) + return -1; - // Set FMMU's + // Set FMMU's - if (desc->fmmu0) - { - if (unlikely(!slave->process_data)) { - printk(KERN_ERR "EtherCAT: Warning - Slave %04X is not assigned to any" - " process data object!\n", slave->station_address); - return -1; - } + if (desc->fmmu0) + { + if (unlikely(!slave->process_data)) { + printk(KERN_ERR "EtherCAT: Warning - Slave %04X is not assigned to any" + " process data object!\n", slave->station_address); + return -1; + } - memcpy(fmmu, desc->fmmu0, 16); + memcpy(fmmu, desc->fmmu0, 16); - fmmu[0] = slave->logical_address & 0x000000FF; - fmmu[1] = (slave->logical_address & 0x0000FF00) >> 8; - fmmu[2] = (slave->logical_address & 0x00FF0000) >> 16; - fmmu[3] = (slave->logical_address & 0xFF000000) >> 24; + fmmu[0] = slave->logical_address & 0x000000FF; + fmmu[1] = (slave->logical_address & 0x0000FF00) >> 8; + fmmu[2] = (slave->logical_address & 0x00FF0000) >> 16; + fmmu[3] = (slave->logical_address & 0xFF000000) >> 24; - EtherCAT_command_write(&cmd, slave->station_address, 0x0600, 16, fmmu); + ec_command_write(&cmd, slave->station_address, 0x0600, 16, fmmu); - if (unlikely(EtherCAT_simple_send_receive(master, &cmd) < 0)) - return -1; + if (unlikely(ec_simple_send_receive(master, &cmd) < 0)) + return -1; - if (unlikely(cmd.working_counter != 1)) { - printk(KERN_ERR "EtherCAT: Setting FMMU0 - Slave %04X did not" - " respond!\n", slave->station_address); - return -1; + if (unlikely(cmd.working_counter != 1)) { + printk(KERN_ERR "EtherCAT: Setting FMMU0 - Slave %04X did not" + " respond!\n", slave->station_address); + return -1; + } } - } - // Set Sync Managers + // Set Sync Managers - if (desc->type != ECAT_ST_MAILBOX) - { - if (desc->sm0) + if (desc->type != EC_MAILBOX_SLAVE) { - EtherCAT_command_write(&cmd, slave->station_address, 0x0800, 8, - desc->sm0); + if (desc->sm0) + { + ec_command_write(&cmd, slave->station_address, 0x0800, 8, + desc->sm0); - if (unlikely(EtherCAT_simple_send_receive(master, &cmd) < 0)) - return -1; + if (unlikely(ec_simple_send_receive(master, &cmd) < 0)) + return -1; - if (unlikely(cmd.working_counter != 1)) { - printk(KERN_ERR "EtherCAT: Setting SM0 - Slave %04X did not" - " respond!\n", slave->station_address); - return -1; + if (unlikely(cmd.working_counter != 1)) { + printk(KERN_ERR "EtherCAT: Setting SM0 - Slave %04X did not" + " respond!\n", slave->station_address); + return -1; + } + } + + if (desc->sm1) + { + ec_command_write(&cmd, slave->station_address, 0x0808, 8, + desc->sm1); + + if (unlikely(ec_simple_send_receive(master, &cmd) < 0)) + return -1; + + if (unlikely(cmd.working_counter != 1)) { + printk(KERN_ERR "EtherCAT: Setting SM1 - Slave %04X did not" + " respond!\n", slave->station_address); + return -1; + } } } - if (desc->sm1) + if (desc->sm2) { - EtherCAT_command_write(&cmd, slave->station_address, 0x0808, 8, - desc->sm1); + ec_command_write(&cmd, slave->station_address, 0x0810, 8, desc->sm2); - if (unlikely(EtherCAT_simple_send_receive(master, &cmd) < 0)) + if (unlikely(ec_simple_send_receive(master, &cmd) < 0)) return -1; if (unlikely(cmd.working_counter != 1)) { - printk(KERN_ERR "EtherCAT: Setting SM1 - Slave %04X did not" + printk(KERN_ERR "EtherCAT: Setting SM2 - Slave %04X did not" " respond!\n", slave->station_address); return -1; } } - } - if (desc->sm2) - { - EtherCAT_command_write(&cmd, slave->station_address, 0x0810, 8, desc->sm2); + if (desc->sm3) + { + ec_command_write(&cmd, slave->station_address, 0x0818, 8, desc->sm3); - if (unlikely(EtherCAT_simple_send_receive(master, &cmd) < 0)) - return -1; + if (unlikely(ec_simple_send_receive(master, &cmd) < 0)) + return -1; - if (unlikely(cmd.working_counter != 1)) { - printk(KERN_ERR "EtherCAT: Setting SM2 - Slave %04X did not respond!\n", - slave->station_address); - return -1; + if (unlikely(cmd.working_counter != 1)) { + printk(KERN_ERR "EtherCAT: Setting SM3 - Slave %04X did not" + " respond!\n", slave->station_address); + return -1; + } } - } - if (desc->sm3) - { - EtherCAT_command_write(&cmd, slave->station_address, 0x0818, 8, desc->sm3); - - if (unlikely(EtherCAT_simple_send_receive(master, &cmd) < 0)) + // Change state to SAVEOP + if (unlikely(ec_state_change(master, slave, EC_SLAVE_STATE_SAVEOP) != 0)) return -1; - if (unlikely(cmd.working_counter != 1)) { - printk(KERN_ERR "EtherCAT: Setting SM3 - Slave %04X did not respond!\n", - slave->station_address); + // Change state to OP + if (unlikely(ec_state_change(master, slave, EC_SLAVE_STATE_OP) != 0)) return -1; - } } - // Change state to SAVEOP - if (unlikely(EtherCAT_state_change(master, slave, ECAT_STATE_SAVEOP) != 0)) - return -1; - - // Change state to OP - if (unlikely(EtherCAT_state_change(master, slave, ECAT_STATE_OP) != 0)) - return -1; - return 0; } @@ -955,12 +996,18 @@ int EtherCAT_activate_slave(EtherCAT_master_t *master, @return 0 bei Erfolg, sonst < 0 */ -int EtherCAT_deactivate_slave(EtherCAT_master_t *master, - EtherCAT_slave_t *slave) +int EtherCAT_rt_deactivate_slaves(ec_master_t *master) { - if (unlikely(EtherCAT_state_change(master, slave, - ECAT_STATE_INIT) != 0)) - return -1; + ec_slave_t *slave; + unsigned int i; + + for (i = 0; i < master->bus_slaves_count; i++) + { + slave = master->bus_slaves + 1; + + if (unlikely(ec_state_change(master, slave, EC_SLAVE_STATE_INIT) != 0)) + return -1; + } return 0; } @@ -977,14 +1024,14 @@ int EtherCAT_deactivate_slave(EtherCAT_master_t *master, @return 0 bei Erfolg, sonst < 0 */ -int EtherCAT_process_data_cycle(EtherCAT_master_t *master, unsigned int domain, - unsigned int timeout_us) +int EtherCAT_rt_domain_cycle(ec_master_t *master, unsigned int domain, + unsigned int timeout_us) { unsigned int i; - EtherCAT_domain_t *dom; + ec_domain_t *dom; unsigned long start_ticks, end_ticks, timeout_ticks; - ecat_output_lost_frames(master); // Evtl. verlorene Frames ausgeben + ec_output_lost_frames(master); // Evtl. verlorene Frames ausgeben // Domäne bestimmen dom = NULL; @@ -1000,13 +1047,12 @@ int EtherCAT_process_data_cycle(EtherCAT_master_t *master, unsigned int domain, return -1; } - EtherCAT_command_logical_read_write(&dom->command, - dom->logical_offset, dom->data_size, - dom->data); + ec_command_logical_read_write(&dom->command, dom->logical_offset, + dom->data_size, dom->data); rdtscl(start_ticks); // Sendezeit nehmen - if (unlikely(EtherCAT_simple_send(master, &dom->command) < 0)) { + if (unlikely(ec_simple_send(master, &dom->command) < 0)) { printk(KERN_ERR "EtherCAT: Could not send process data command!\n"); return -1; } @@ -1015,27 +1061,27 @@ int EtherCAT_process_data_cycle(EtherCAT_master_t *master, unsigned int domain, // Warten do { - EtherCAT_device_call_isr(master->dev); + ec_device_call_isr(&master->device); rdtscl(end_ticks); // Empfangszeit nehmen } - while (unlikely(master->dev->state == ECAT_DS_SENT + while (unlikely(master->device.state == EC_DEVICE_STATE_SENT && end_ticks - start_ticks < timeout_ticks)); master->bus_time = (end_ticks - start_ticks) * 1000 / cpu_khz; if (unlikely(end_ticks - start_ticks >= timeout_ticks)) { - master->dev->state = ECAT_DS_READY; + master->device.state = EC_DEVICE_STATE_READY; master->frames_lost++; - ecat_output_lost_frames(master); + ec_output_lost_frames(master); return -1; } - if (unlikely(EtherCAT_simple_receive(master, &dom->command) < 0)) { + if (unlikely(ec_simple_receive(master, &dom->command) < 0)) { printk(KERN_ERR "EtherCAT: Could not receive cyclic command!\n"); return -1; } - if (unlikely(dom->command.state != ECAT_CS_RECEIVED)) { + if (unlikely(dom->command.state != EC_COMMAND_STATE_RECEIVED)) { printk(KERN_WARNING "EtherCAT: Process data command not received!\n"); return -1; } @@ -1054,68 +1100,10 @@ int EtherCAT_process_data_cycle(EtherCAT_master_t *master, unsigned int domain, /*****************************************************************************/ -/** - Gibt Frame-Inhalte zwecks Debugging aus. - - @param master EtherCAT-Master -*/ - -void output_debug_data(const EtherCAT_master_t *master) -{ - unsigned int i; - - printk(KERN_DEBUG "EtherCAT: tx_data content (%i Bytes):\n", - master->tx_data_length); - - printk(KERN_DEBUG); - for (i = 0; i < master->tx_data_length; i++) - { - printk("%02X ", master->tx_data[i]); - if ((i + 1) % 16 == 0) printk("\n" KERN_DEBUG); - } - printk("\n"); - - printk(KERN_DEBUG "EtherCAT: rx_data content (%i Bytes):\n", - master->rx_data_length); - - printk(KERN_DEBUG); - for (i = 0; i < master->rx_data_length; i++) - { - printk("%02X ", master->rx_data[i]); - if ((i + 1) % 16 == 0) printk("\n" KERN_DEBUG); - } - printk("\n"); -} - -/*****************************************************************************/ - -/** - Gibt von Zeit zu Zeit die Anzahl verlorener Frames aus. - - @param master EtherCAT-Master -*/ - -void ecat_output_lost_frames(EtherCAT_master_t *master) -{ - unsigned long int t; - - if (master->frames_lost) { - rdtscl(t); - if ((t - master->t_lost_output) / cpu_khz > 1000) { - printk(KERN_ERR "EtherCAT: %u frame(s) LOST!\n", master->frames_lost); - master->frames_lost = 0; - master->t_lost_output = t; - } - } -} - -/*****************************************************************************/ - -EXPORT_SYMBOL(EtherCAT_master_open); -EXPORT_SYMBOL(EtherCAT_master_close); -EXPORT_SYMBOL(EtherCAT_activate_slave); -EXPORT_SYMBOL(EtherCAT_deactivate_slave); -EXPORT_SYMBOL(EtherCAT_process_data_cycle); +EXPORT_SYMBOL(EtherCAT_rt_register_slave); +EXPORT_SYMBOL(EtherCAT_rt_activate_slaves); +EXPORT_SYMBOL(EtherCAT_rt_deactivate_slaves); +EXPORT_SYMBOL(EtherCAT_rt_domain_cycle); /*****************************************************************************/ diff --git a/master/master.h b/master/master.h new file mode 100644 index 0000000000000000000000000000000000000000..d3eb79875bc2a9527d30b8c87a961376736fa6d1 --- /dev/null +++ b/master/master.h @@ -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: *** +*/ diff --git a/drivers/ec_module.c b/master/module.c similarity index 53% rename from drivers/ec_module.c rename to master/module.c index bd8adf8fea41077531447ce348e80fed515fb6a2..04a35082b559f2fc34d8d55bdb3f7d6a3297d22e 100644 --- a/drivers/ec_module.c +++ b/master/module.c @@ -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; + } + + 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; } - return EtherCAT_master_open(&ecat_masters[index], device); + 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); + +/*****************************************************************************/ diff --git a/drivers/ec_slave.c b/master/slave.c similarity index 96% rename from drivers/ec_slave.c rename to master/slave.c index 1d7306f1d8d3f1977ca7ee800fbc3cc31e59e381..e510e9e1f1372fc66b67245e8d329570feaae878 100644 --- a/drivers/ec_slave.c +++ b/master/slave.c @@ -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 /*****************************************************************************/ diff --git a/drivers/ec_slave.h b/master/slave.h similarity index 81% rename from drivers/ec_slave.h rename to master/slave.h index df9c7aedef071a13be36e42bf779bbd46fd7b5c9..dff420107fb975c9281460d5c6711422889686e0 100644 --- a/drivers/ec_slave.h +++ b/master/slave.h @@ -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 /*****************************************************************************/ diff --git a/drivers/ec_types.c b/master/types.c similarity index 80% rename from drivers/ec_types.c rename to master/types.c index 5030beb53037937f6ec8b3d23f4703af5e860516..4f78c643997f249a1b6cb3fe986fae2aef6a042d 100644 --- a/drivers/ec_types.c +++ b/master/types.c @@ -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); - -/*****************************************************************************/ diff --git a/drivers/ec_types.h b/master/types.h similarity index 75% rename from drivers/ec_types.h rename to master/types.h index e368b003e736fe02c127a4e57c3775836c1c719a..d959f47cb6c8b1f8a0fcb4426159476e3e7e7028 100644 --- a/drivers/ec_types.h +++ b/master/types.h @@ -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 diff --git a/mini/Makefile b/mini/Makefile index 6e4e2863fda7d0246cc10f945426b8011daaf834..aeaa1867ded6b07a0e7fafcaa5d038b1cf09b6bc 100644 --- a/mini/Makefile +++ b/mini/Makefile @@ -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 #---------------------------------------------------------------- diff --git a/mini/ec_mini.c b/mini/ec_mini.c deleted file mode 100644 index e7f5e74d1f335d6cb0460665c6f89f446ec2b8ae..0000000000000000000000000000000000000000 --- a/mini/ec_mini.c +++ /dev/null @@ -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: *** -*/ diff --git a/mini/mini.c b/mini/mini.c new file mode 100644 index 0000000000000000000000000000000000000000..4a0fd296557e859fd44f7450c36a2c18dd6608e1 --- /dev/null +++ b/mini/mini.c @@ -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: *** +*/ diff --git a/rt/msr_module.c b/rt/msr_module.c index 224d8b3fef437e734d58544016fdaaf11e71a11f..7b4c1cde88fcc1c15f03a594414f93fd73d2c1a5 100644 --- a/rt/msr_module.c +++ b/rt/msr_module.c @@ -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); /*****************************************************************************/