From 8507108ba863a805383af548006044e4a26aea74 Mon Sep 17 00:00:00 2001 From: Florian Pose <fp@igh-essen.com> Date: Fri, 17 Mar 2006 14:21:35 +0000 Subject: [PATCH] =?UTF-8?q?MERGE=20branches/async=20->=20trunk=20(alle=20U?= =?UTF-8?q?nterschiede=20=C3=BCbernommen)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devices/8139too.c | 64 +++++++++--------- devices/ecdev.h | 38 +++++++++++ include/EtherCAT_dev.h | 33 ---------- include/EtherCAT_rt.h | 120 --------------------------------- include/EtherCAT_si.h | 71 -------------------- include/ecrt.h | 146 +++++++++++++++++++++++++++++++++++++++++ master/canopen.c | 71 ++++++++++---------- master/command.c | 1 - master/device.c | 28 ++++---- master/device.h | 6 +- master/domain.c | 94 ++++++++++++-------------- master/domain.h | 6 +- master/master.c | 136 +++++++++++++++++++++++++------------- master/module.c | 45 +++++++------ master/slave.c | 1 - master/types.c | 28 ++++---- master/types.h | 6 +- mini/mini.c | 73 +++++++++++---------- rt/msr_module.c | 94 +++++++++++++++++--------- 19 files changed, 541 insertions(+), 520 deletions(-) create mode 100644 devices/ecdev.h delete mode 100644 include/EtherCAT_dev.h delete mode 100644 include/EtherCAT_rt.h delete mode 100644 include/EtherCAT_si.h create mode 100644 include/ecrt.h diff --git a/devices/8139too.c b/devices/8139too.c index 13d75430..55091701 100644 --- a/devices/8139too.c +++ b/devices/8139too.c @@ -134,7 +134,7 @@ /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ -#include "../include/EtherCAT_dev.h" +#include "ecdev.h" #define EC_LIT(X) #X #define EC_STR(X) EC_LIT(X) @@ -1028,7 +1028,7 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev, if (board_idx == ec_device_index) { printk(KERN_INFO "Registering EtherCAT device...\n"); - rtl_ec_dev = EtherCAT_dev_register(ec_device_master_index, dev, + rtl_ec_dev = ecdev_register(ec_device_master_index, dev, rtl8139_interrupt, THIS_MODULE); if (rtl_ec_dev) strcpy(dev->name, "ec0"); @@ -1092,7 +1092,7 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev, /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ /* EtherCAT-Karten nicht beim Stack anmelden. */ - if (!EtherCAT_dev_is_ec(rtl_ec_dev, dev)) + if (!ecdev_is_ec(rtl_ec_dev, dev)) { DPRINTK("About to register device named %s (%p)...\n", dev->name, dev); i = register_netdev (dev); @@ -1190,7 +1190,7 @@ static void __devexit rtl8139_remove_one (struct pci_dev *pdev) /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ - if (!EtherCAT_dev_is_ec(rtl_ec_dev, dev)) + if (!ecdev_is_ec(rtl_ec_dev, dev)) { unregister_netdev (dev); } @@ -1403,7 +1403,7 @@ static int rtl8139_open (struct net_device *dev) printk(KERN_DEBUG "%s: open\n", dev->name); #endif - if (!EtherCAT_dev_is_ec(rtl_ec_dev, dev)) + if (!ecdev_is_ec(rtl_ec_dev, dev)) { retval = request_irq(dev->irq, rtl8139_interrupt, SA_SHIRQ, dev->name, dev); if (retval) @@ -1420,7 +1420,7 @@ static int rtl8139_open (struct net_device *dev) { /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ - if (!EtherCAT_dev_is_ec(rtl_ec_dev, dev)) + if (!ecdev_is_ec(rtl_ec_dev, dev)) { free_irq(dev->irq, dev); } @@ -1445,7 +1445,7 @@ static int rtl8139_open (struct net_device *dev) /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ - if (!EtherCAT_dev_is_ec(rtl_ec_dev, dev)) + if (!ecdev_is_ec(rtl_ec_dev, dev)) { netif_start_queue (dev); @@ -1471,10 +1471,10 @@ static void rtl_check_media (struct net_device *dev, unsigned int init_media) { struct rtl8139_private *tp = netdev_priv(dev); - if (EtherCAT_dev_is_ec(rtl_ec_dev, dev)) { + if (ecdev_is_ec(rtl_ec_dev, dev)) { void __iomem *ioaddr = tp->mmio_addr; uint16_t state = RTL_R16(BasicModeStatus) & BMSR_LSTATUS; - EtherCAT_dev_link_state(rtl_ec_dev, state ? 1 : 0); + ecdev_link_state(rtl_ec_dev, state ? 1 : 0); } else if (tp->phys[0] >= 0) { mii_check_media(&tp->mii, netif_msg_link(tp), init_media); @@ -1545,7 +1545,7 @@ static void rtl8139_hw_start (struct net_device *dev) /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ - if (!EtherCAT_dev_is_ec(rtl_ec_dev, dev)) + if (!ecdev_is_ec(rtl_ec_dev, dev)) { /* Enable all known interrupts by setting the interrupt mask. */ RTL_W16 (IntrMask, rtl8139_intr_mask); @@ -1814,7 +1814,7 @@ static void rtl8139_tx_timeout (struct net_device *dev) /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ - if (!EtherCAT_dev_is_ec(rtl_ec_dev, dev)) + if (!ecdev_is_ec(rtl_ec_dev, dev)) { spin_lock(&tp->rx_lock); @@ -1864,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 (!EtherCAT_dev_is_ec(rtl_ec_dev, dev)) dev_kfree_skb(skb); + if (!ecdev_is_ec(rtl_ec_dev, dev)) dev_kfree_skb(skb); } else { - if (!EtherCAT_dev_is_ec(rtl_ec_dev, dev)) dev_kfree_skb(skb); + if (!ecdev_is_ec(rtl_ec_dev, dev)) dev_kfree_skb(skb); tp->stats.tx_dropped++; return 0; } - if (!EtherCAT_dev_is_ec(rtl_ec_dev, dev)) + if (!ecdev_is_ec(rtl_ec_dev, dev)) { spin_lock_irq(&tp->lock); } @@ -1890,7 +1890,7 @@ static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev) /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ - if (!EtherCAT_dev_is_ec(rtl_ec_dev, dev)) + if (!ecdev_is_ec(rtl_ec_dev, dev)) { if ((tp->cur_tx - NUM_TX_DESC) == tp->dirty_tx) netif_stop_queue (dev); @@ -1965,7 +1965,7 @@ static void rtl8139_tx_interrupt (struct net_device *dev, /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ #ifndef RTL8139_NDEBUG - if (!EtherCAT_dev_is_ec(rtl_ec_dev, dev) && tp->cur_tx - dirty_tx > NUM_TX_DESC) { + if (!ecdev_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; @@ -1981,7 +1981,7 @@ static void rtl8139_tx_interrupt (struct net_device *dev, /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ - if (!EtherCAT_dev_is_ec(rtl_ec_dev, dev)) + if (!ecdev_is_ec(rtl_ec_dev, dev)) { netif_wake_queue (dev); } @@ -2120,7 +2120,7 @@ static int rtl8139_rx(struct net_device *dev, struct rtl8139_private *tp, RTL_R16 (RxBufAddr), RTL_R16 (RxBufPtr), RTL_R8 (ChipCmd)); - while ((EtherCAT_dev_is_ec(rtl_ec_dev, dev) || netif_running(dev)) + while ((ecdev_is_ec(rtl_ec_dev, dev) || netif_running(dev)) && received < budget && (RTL_R8 (ChipCmd) & RxBufEmpty) == 0) { u32 ring_offset = cur_rx % RX_BUF_LEN; @@ -2137,7 +2137,7 @@ static int rtl8139_rx(struct net_device *dev, struct rtl8139_private *tp, /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ - if (!EtherCAT_dev_is_ec(rtl_ec_dev, dev) && netif_msg_rx_status(tp)) + if (!ecdev_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); @@ -2193,7 +2193,7 @@ no_early_rx: /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ - if (!EtherCAT_dev_is_ec(rtl_ec_dev, dev)) + if (!ecdev_is_ec(rtl_ec_dev, dev)) { /* Malloc up new buffer, compatible with net-2e. */ /* Omit the four octet CRC from the length. */ @@ -2226,7 +2226,7 @@ no_early_rx: } else { - EtherCAT_dev_receive(rtl_ec_dev, + ecdev_receive(rtl_ec_dev, &rx_ring[ring_offset + 4] + ETH_HLEN, pkt_size - ETH_HLEN); dev->last_rx = jiffies; @@ -2356,7 +2356,7 @@ irqreturn_t rtl8139_interrupt (int irq, void *dev_instance, /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ - if (EtherCAT_dev_is_ec(rtl_ec_dev, dev)) + if (ecdev_is_ec(rtl_ec_dev, dev)) { status = RTL_R16 (IntrStatus); } @@ -2380,7 +2380,7 @@ irqreturn_t rtl8139_interrupt (int irq, void *dev_instance, /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ - if (!EtherCAT_dev_is_ec(rtl_ec_dev, dev)) + if (!ecdev_is_ec(rtl_ec_dev, dev)) { /* close possible race's with dev_close */ if (unlikely(!netif_running(dev))) { @@ -2408,7 +2408,7 @@ irqreturn_t rtl8139_interrupt (int irq, void *dev_instance, if (status & RxAckBits) { - if (!EtherCAT_dev_is_ec(rtl_ec_dev, dev)) + if (!ecdev_is_ec(rtl_ec_dev, dev)) { /* Polling vormerken */ if (netif_rx_schedule_prep(dev)) { @@ -2438,7 +2438,7 @@ irqreturn_t rtl8139_interrupt (int irq, void *dev_instance, out: /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ - if (!EtherCAT_dev_is_ec(rtl_ec_dev, dev)) + if (!ecdev_is_ec(rtl_ec_dev, dev)) { spin_unlock (&tp->lock); } @@ -2472,7 +2472,7 @@ static int rtl8139_close (struct net_device *dev) /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ - if (!EtherCAT_dev_is_ec(rtl_ec_dev, dev)) + if (!ecdev_is_ec(rtl_ec_dev, dev)) { netif_stop_queue(dev); if (tp->thr_pid >= 0) { @@ -2737,7 +2737,7 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ - if (EtherCAT_dev_is_ec(rtl_ec_dev, dev) || !netif_running(dev)) + if (ecdev_is_ec(rtl_ec_dev, dev) || !netif_running(dev)) return -EINVAL; /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ @@ -2758,7 +2758,7 @@ static struct net_device_stats *rtl8139_get_stats (struct net_device *dev) /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ - if (EtherCAT_dev_is_ec(rtl_ec_dev, dev) || netif_running(dev)) + if (ecdev_is_ec(rtl_ec_dev, dev) || netif_running(dev)) { spin_lock_irqsave (&tp->lock, flags); tp->stats.rx_missed_errors += RTL_R32 (RxMissed); @@ -2845,7 +2845,7 @@ static int rtl8139_suspend (struct pci_dev *pdev, pm_message_t state) /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ - if (EtherCAT_dev_is_ec(rtl_ec_dev, dev) || !netif_running (dev)) + if (ecdev_is_ec(rtl_ec_dev, dev) || !netif_running (dev)) return 0; /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ @@ -2878,7 +2878,7 @@ static int rtl8139_resume (struct pci_dev *pdev) /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ - if (EtherCAT_dev_is_ec(rtl_ec_dev, dev) || !netif_running (dev)) + if (ecdev_is_ec(rtl_ec_dev, dev) || !netif_running (dev)) return 0; /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ @@ -2935,7 +2935,7 @@ static int __init rtl8139_init_module (void) 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); + ecdev_unregister(ec_device_master_index, rtl_ec_dev); rtl_ec_dev = NULL; } @@ -2955,7 +2955,7 @@ static void __exit rtl8139_cleanup_module (void) if (rtl_ec_dev) { printk(KERN_INFO "Unregistering RTL8139-EtherCAT device...\n"); - EtherCAT_dev_unregister(ec_device_master_index, rtl_ec_dev); + ecdev_unregister(ec_device_master_index, rtl_ec_dev); rtl_ec_dev = NULL; } diff --git a/devices/ecdev.h b/devices/ecdev.h new file mode 100644 index 00000000..b5633f94 --- /dev/null +++ b/devices/ecdev.h @@ -0,0 +1,38 @@ +/****************************************************************************** + * + * 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 irqreturn_t (*ec_isr_t)(int, void *, struct pt_regs *); + +/*****************************************************************************/ +// Registration functions + +ec_device_t *ecdev_register(unsigned int master_index, + struct net_device *net_dev, ec_isr_t isr, + struct module *module); +void ecdev_unregister(unsigned int master_index, ec_device_t *device); + +/*****************************************************************************/ +// Device methods + +int ecdev_is_ec(const ec_device_t *device, const struct net_device *net_dev); +void ecdev_receive(ec_device_t *device, const void *data, size_t size); +void ecdev_link_state(ec_device_t *device, uint8_t newstate); + +/*****************************************************************************/ + +#endif diff --git a/include/EtherCAT_dev.h b/include/EtherCAT_dev.h deleted file mode 100644 index add3ff8d..00000000 --- a/include/EtherCAT_dev.h +++ /dev/null @@ -1,33 +0,0 @@ -/****************************************************************************** - * - * 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; - -/*****************************************************************************/ - -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, ec_device_t *); - -int EtherCAT_dev_is_ec(const ec_device_t *, const struct net_device *); -void EtherCAT_dev_receive(ec_device_t *, const void *, size_t); -void EtherCAT_dev_link_state(ec_device_t *, uint8_t); - -/*****************************************************************************/ - -#endif diff --git a/include/EtherCAT_rt.h b/include/EtherCAT_rt.h deleted file mode 100644 index ca1da0c0..00000000 --- a/include/EtherCAT_rt.h +++ /dev/null @@ -1,120 +0,0 @@ -/****************************************************************************** - * - * Oeffentliche EtherCAT-Schnittstellen fuer Echtzeitprozesse. - * - * $Id$ - * - *****************************************************************************/ - -#ifndef _ETHERCAT_RT_H_ -#define _ETHERCAT_RT_H_ - -/*****************************************************************************/ - -struct ec_master; -typedef struct ec_master ec_master_t; - -struct ec_domain; -typedef struct ec_domain ec_domain_t; - -struct ec_slave; -typedef struct ec_slave ec_slave_t; - -typedef enum -{ - ec_sync, - ec_async -} -ec_domain_mode_t; - -typedef enum -{ - ec_status, - ec_control, - ec_ipvalue, - ec_opvalue -} -ec_field_type_t; - -typedef struct -{ - void **data; - const char *address; - const char *vendor; - const char *product; - ec_field_type_t field_type; - unsigned int field_index; - unsigned int field_count; -} -ec_field_init_t; - -/*****************************************************************************/ -// Master request functions - -ec_master_t *EtherCAT_rt_request_master(unsigned int master_index); - -void EtherCAT_rt_release_master(ec_master_t *master); - -/*****************************************************************************/ -// Master methods - -ec_domain_t *EtherCAT_rt_master_register_domain(ec_master_t *master, - ec_domain_mode_t mode, - unsigned int timeout_us); - -int EtherCAT_rt_master_activate(ec_master_t *master); -int EtherCAT_rt_master_deactivate(ec_master_t *master); - -void EtherCAT_rt_master_xio(ec_master_t *master); - -void EtherCAT_rt_master_debug(ec_master_t *master, int level); -void EtherCAT_rt_master_print(const ec_master_t *master); - -/*****************************************************************************/ -// Domain Methods - -ec_slave_t *EtherCAT_rt_register_slave_field(ec_domain_t *domain, - const char *address, - const char *vendor_name, - const char *product_name, - void **data_ptr, - ec_field_type_t field_type, - unsigned int field_index, - unsigned int field_count); - -int EtherCAT_rt_register_domain_fields(ec_domain_t *domain, - ec_field_init_t *fields); - -void EtherCAT_rt_domain_queue(ec_domain_t *domain); -void EtherCAT_rt_domain_process(ec_domain_t *domain); - -/*****************************************************************************/ -// Slave Methods - -int EtherCAT_rt_canopen_sdo_write(ec_slave_t *slave, - uint16_t sdo_index, - uint8_t sdo_subindex, - uint32_t value, - size_t size); - -int EtherCAT_rt_canopen_sdo_read(ec_slave_t *slave, - uint16_t sdo_index, - uint8_t sdo_subindex, - uint32_t *value); - -int EtherCAT_rt_canopen_sdo_addr_write(ec_master_t *master, - const char *addr, - uint16_t sdo_index, - uint8_t sdo_subindex, - uint32_t value, - size_t size); - -int EtherCAT_rt_canopen_sdo_addr_read(ec_master_t *master, - const char *addr, - uint16_t sdo_index, - uint8_t sdo_subindex, - uint32_t *value); - -/*****************************************************************************/ - -#endif diff --git a/include/EtherCAT_si.h b/include/EtherCAT_si.h deleted file mode 100644 index 744994f7..00000000 --- a/include/EtherCAT_si.h +++ /dev/null @@ -1,71 +0,0 @@ -/****************************************************************************** - * - * E t h e r C A T _ s i . h - * - * EtherCAT Slave-Interface. - * - * $Id$ - * - *****************************************************************************/ - -#include <asm/byteorder.h> - -/*****************************************************************************/ - -// Bitwise read/write macros - -#define EC_READ_BIT(PD, CH) (*((uint8_t *) (PD)) >> (CH)) & 0x01) - -#define EC_WRITE_BIT(PD, CH, VAL) \ - do { \ - if (VAL) *((uint8_t *) (PD)) |= (1 << (CH)); \ - else *((uint8_t *) (PD)) &= ~(1 << (CH)); \ - } while (0) - -/*****************************************************************************/ - -// Read macros - -#define EC_READ_U8(PD) ((uint8_t) *((uint8_t *) (PD))) -#define EC_READ_S8(PD) ((int8_t) *((uint8_t *) (PD))) - -#define EC_READ_U16(PD) ((uint16_t) le16_to_cpup((void *) (PD))) -#define EC_READ_S16(PD) ((int16_t) le16_to_cpup((void *) (PD))) - -#define EC_READ_U32(PD) ((uint32_t) le32_to_cpup((void *) (PD))) -#define EC_READ_S32(PD) ((int32_t) le32_to_cpup((void *) (PD))) - -/*****************************************************************************/ - -// Write macros - -#define EC_WRITE_U8(PD, VAL) \ - do { \ - *((uint8_t *)(PD)) = ((uint8_t) (VAL)); \ - } while (0) - -#define EC_WRITE_S8(PD, VAL) EC_WRITE_U8(PD, VAL) - -#define EC_WRITE_U16(PD, VAL) \ - do { \ - *((uint16_t *) (PD)) = (uint16_t) (VAL); \ - cpu_to_le16s(PD); \ - } while (0) - -#define EC_WRITE_S16(PD, VAL) EC_WRITE_U16(PD, VAL) - -#define EC_WRITE_U32(PD, VAL) \ - do { \ - *((uint32_t *) (PD)) = (uint32_t) (VAL); \ - cpu_to_le16s(PD); \ - } while (0) - -#define EC_WRITE_S32(PD, VAL) EC_WRITE_U32(PD, VAL) - -/*****************************************************************************/ - -/* Emacs-Konfiguration -;;; Local Variables: *** -;;; c-basic-offset:4 *** -;;; End: *** -*/ diff --git a/include/ecrt.h b/include/ecrt.h new file mode 100644 index 00000000..110eea5a --- /dev/null +++ b/include/ecrt.h @@ -0,0 +1,146 @@ +/****************************************************************************** + * + * Oeffentliche EtherCAT-Schnittstellen fuer Echtzeitprozesse. + * + * $Id$ + * + *****************************************************************************/ + +#ifndef _ETHERCAT_RT_H_ +#define _ETHERCAT_RT_H_ + +#include <asm/byteorder.h> + +/*****************************************************************************/ + +struct ec_master; +typedef struct ec_master ec_master_t; + +struct ec_domain; +typedef struct ec_domain ec_domain_t; + +struct ec_slave; +typedef struct ec_slave ec_slave_t; + +typedef struct +{ + void **data_ptr; + const char *slave_address; + const char *vendor_name; + const char *product_name; + const char *field_name; + unsigned int field_index; + unsigned int field_count; +} +ec_field_init_t; + +/*****************************************************************************/ +// Master request functions + +ec_master_t *ecrt_request_master(unsigned int master_index); +void ecrt_release_master(ec_master_t *master); + +/*****************************************************************************/ +// Master methods + +ec_domain_t *ecrt_master_create_domain(ec_master_t *master); +int ecrt_master_activate(ec_master_t *master); +void ecrt_master_deactivate(ec_master_t *master); +void ecrt_master_sync_io(ec_master_t *master); +void ecrt_master_async_send(ec_master_t *master); +void ecrt_master_async_receive(ec_master_t *master); +void ecrt_master_debug(ec_master_t *master, int level); +void ecrt_master_print(const ec_master_t *master); +int ecrt_master_sdo_write(ec_master_t *master, + const char *slave_addr, + uint16_t sdo_index, + uint8_t sdo_subindex, + uint32_t value, + size_t size); +int ecrt_master_sdo_read(ec_master_t *master, + const char *slave_addr, + uint16_t sdo_index, + uint8_t sdo_subindex, + uint32_t *value); + +/*****************************************************************************/ +// Domain Methods + +ec_slave_t *ecrt_domain_register_field(ec_domain_t *domain, + const char *address, + const char *vendor_name, + const char *product_name, + void **data_ptr, + const char *field_name, + unsigned int field_index, + unsigned int field_count); +int ecrt_domain_register_field_list(ec_domain_t *domain, + ec_field_init_t *fields); +void ecrt_domain_queue(ec_domain_t *domain); +void ecrt_domain_process(ec_domain_t *domain); + +/*****************************************************************************/ +// Slave Methods + +int ecrt_slave_sdo_write(ec_slave_t *slave, + uint16_t sdo_index, + uint8_t sdo_subindex, + uint32_t value, + size_t size); +int ecrt_slave_sdo_read(ec_slave_t *slave, + uint16_t sdo_index, + uint8_t sdo_subindex, + uint32_t *value); + +/*****************************************************************************/ +// Bitwise read/write macros + +#define EC_READ_BIT(PD, CH) (*((uint8_t *) (PD)) >> (CH)) & 0x01) + +#define EC_WRITE_BIT(PD, CH, VAL) \ + do { \ + if (VAL) *((uint8_t *) (PD)) |= (1 << (CH)); \ + else *((uint8_t *) (PD)) &= ~(1 << (CH)); \ + } while (0) + +/*****************************************************************************/ +// Read macros + +#define EC_READ_U8(PD) ((uint8_t) *((uint8_t *) (PD))) +#define EC_READ_S8(PD) ((int8_t) *((uint8_t *) (PD))) + +#define EC_READ_U16(PD) ((uint16_t) le16_to_cpup((void *) (PD))) +#define EC_READ_S16(PD) ((int16_t) le16_to_cpup((void *) (PD))) + +#define EC_READ_U32(PD) ((uint32_t) le32_to_cpup((void *) (PD))) +#define EC_READ_S32(PD) ((int32_t) le32_to_cpup((void *) (PD))) + +/*****************************************************************************/ +// Write macros + +#define EC_WRITE_U8(PD, VAL) \ + do { \ + *((uint8_t *)(PD)) = ((uint8_t) (VAL)); \ + } while (0) + +#define EC_WRITE_S8(PD, VAL) EC_WRITE_U8(PD, VAL) + +#define EC_WRITE_U16(PD, VAL) \ + do { \ + *((uint16_t *) (PD)) = (uint16_t) (VAL); \ + cpu_to_le16s(PD); \ + } while (0) + +#define EC_WRITE_S16(PD, VAL) EC_WRITE_U16(PD, VAL) + +#define EC_WRITE_U32(PD, VAL) \ + do { \ + *((uint32_t *) (PD)) = (uint32_t) (VAL); \ + cpu_to_le16s(PD); \ + } while (0) + +#define EC_WRITE_S32(PD, VAL) EC_WRITE_U32(PD, VAL) + +/*****************************************************************************/ + +#endif diff --git a/master/canopen.c b/master/canopen.c index f093ada8..d2a85fb6 100644 --- a/master/canopen.c +++ b/master/canopen.c @@ -12,7 +12,6 @@ #include <linux/slab.h> #include <linux/module.h> -#include "../include/EtherCAT_si.h" #include "master.h" /*****************************************************************************/ @@ -21,7 +20,7 @@ Schreibt ein CANopen-SDO (service data object). */ -int EtherCAT_rt_canopen_sdo_write(ec_slave_t *slave, /**< EtherCAT-Slave */ +int ecrt_slave_sdo_write(ec_slave_t *slave, /**< EtherCAT-Slave */ uint16_t sdo_index, /**< SDO-Index */ uint8_t sdo_subindex, /**< SDO-Subindex */ uint32_t value, /**< Neuer Wert */ @@ -114,7 +113,7 @@ int EtherCAT_rt_canopen_sdo_write(ec_slave_t *slave, /**< EtherCAT-Slave */ Liest ein CANopen-SDO (service data object). */ -int EtherCAT_rt_canopen_sdo_read(ec_slave_t *slave, /**< EtherCAT-Slave */ +int ecrt_slave_sdo_read(ec_slave_t *slave, /**< EtherCAT-Slave */ uint16_t sdo_index, /**< SDO-Index */ uint8_t sdo_subindex, /**< SDO-Subindex */ uint32_t *value /**< Speicher für gel. Wert */ @@ -198,29 +197,28 @@ int EtherCAT_rt_canopen_sdo_read(ec_slave_t *slave, /**< EtherCAT-Slave */ /** Schweibt ein CANopen-SDO (Variante mit Angabe des Masters und der Adresse). - Siehe EtherCAT_rt_canopen_sdo_write() + Siehe ecrt_slave_sdo_write() \return 0 wenn alles ok, < 0 bei Fehler */ -int EtherCAT_rt_canopen_sdo_addr_write(ec_master_t *master, - /**< EtherCAT-Master */ - const char *addr, - /**< Addresse, siehe - ec_master_slave_address() */ - uint16_t index, - /**< SDO-Index */ - uint8_t subindex, - /**< SDO-Subindex */ - uint32_t value, - /**< Neuer Wert */ - size_t size - /**< Größe des Datenfeldes */ - ) +int ecrt_master_sdo_write(ec_master_t *master, + /**< EtherCAT-Master */ + const char *addr, + /**< Addresse, siehe ec_master_slave_address() */ + uint16_t index, + /**< SDO-Index */ + uint8_t subindex, + /**< SDO-Subindex */ + uint32_t value, + /**< Neuer Wert */ + size_t size + /**< Größe des Datenfeldes */ + ) { ec_slave_t *slave; if (!(slave = ec_master_slave_address(master, addr))) return -1; - return EtherCAT_rt_canopen_sdo_write(slave, index, subindex, value, size); + return ecrt_slave_sdo_write(slave, index, subindex, value, size); } /*****************************************************************************/ @@ -228,35 +226,34 @@ int EtherCAT_rt_canopen_sdo_addr_write(ec_master_t *master, /** Liest ein CANopen-SDO (Variante mit Angabe des Masters und der Adresse). - Siehe EtherCAT_rt_canopen_sdo_read() + Siehe ecrt_slave_sdo_read() \return 0 wenn alles ok, < 0 bei Fehler */ -int EtherCAT_rt_canopen_sdo_addr_read(ec_master_t *master, - /**< EtherCAT-Slave */ - const char *addr, - /**< Addresse, siehe - ec_master_slave_address() */ - uint16_t index, - /**< SDO-Index */ - uint8_t subindex, - /**< SDO-Subindex */ - uint32_t *value - /**< Speicher für gel. Wert */ - ) +int ecrt_master_sdo_read(ec_master_t *master, + /**< EtherCAT-Slave */ + const char *addr, + /**< Addresse, siehe ec_master_slave_address() */ + uint16_t index, + /**< SDO-Index */ + uint8_t subindex, + /**< SDO-Subindex */ + uint32_t *value + /**< Speicher für gel. Wert */ + ) { ec_slave_t *slave; if (!(slave = ec_master_slave_address(master, addr))) return -1; - return EtherCAT_rt_canopen_sdo_read(slave, index, subindex, value); + return ecrt_slave_sdo_read(slave, index, subindex, value); } /*****************************************************************************/ -EXPORT_SYMBOL(EtherCAT_rt_canopen_sdo_write); -EXPORT_SYMBOL(EtherCAT_rt_canopen_sdo_read); -EXPORT_SYMBOL(EtherCAT_rt_canopen_sdo_addr_write); -EXPORT_SYMBOL(EtherCAT_rt_canopen_sdo_addr_read); +EXPORT_SYMBOL(ecrt_slave_sdo_write); +EXPORT_SYMBOL(ecrt_slave_sdo_read); +EXPORT_SYMBOL(ecrt_master_sdo_write); +EXPORT_SYMBOL(ecrt_master_sdo_read); /*****************************************************************************/ diff --git a/master/command.c b/master/command.c index 60abfb0c..9a8f8d89 100644 --- a/master/command.c +++ b/master/command.c @@ -11,7 +11,6 @@ #include <linux/slab.h> #include <linux/delay.h> -#include "../include/EtherCAT_si.h" #include "command.h" #include "master.h" diff --git a/master/device.c b/master/device.c index 6e998eec..a4c9b998 100644 --- a/master/device.c +++ b/master/device.c @@ -255,9 +255,9 @@ void ec_data_print_diff(const uint8_t *d1, /**< Daten 1 */ \return 0 wenn nein, nicht-null wenn ja. */ -inline int EtherCAT_dev_is_ec(const ec_device_t *device, /**< EtherCAT-Gerät */ - const struct net_device *dev /**< Net-Device */ - ) +inline int ecdev_is_ec(const ec_device_t *device, /**< EtherCAT-Gerät */ + const struct net_device *dev /**< Net-Device */ + ) { return device && device->dev == dev; } @@ -270,10 +270,10 @@ inline int EtherCAT_dev_is_ec(const ec_device_t *device, /**< EtherCAT-Ger Kopiert die empfangenen Daten in den Receive-Buffer. */ -void EtherCAT_dev_receive(ec_device_t *device, /**< EtherCAT-Gerät */ - const void *data, /**< Zeiger auf empfangene Daten */ - size_t size /**< Größe der empfangenen Daten */ - ) +void ecdev_receive(ec_device_t *device, /**< EtherCAT-Gerät */ + const void *data, /**< Zeiger auf empfangene Daten */ + size_t size /**< Größe der empfangenen Daten */ + ) { if (unlikely(device->master->debug_level > 1)) { EC_DBG("Received frame:\n"); @@ -289,11 +289,11 @@ void EtherCAT_dev_receive(ec_device_t *device, /**< EtherCAT-Ger Setzt einen neuen Verbindungszustand. */ -void EtherCAT_dev_link_state(ec_device_t *device, /**< EtherCAT-Gerät */ - uint8_t state /**< Verbindungszustand */ - ) +void ecdev_link_state(ec_device_t *device, /**< EtherCAT-Gerät */ + uint8_t state /**< Verbindungszustand */ + ) { - if (state != device->link_state) { + if (likely(state != device->link_state)) { device->link_state = state; EC_INFO("Link state changed to %s.\n", (state ? "UP" : "DOWN")); } @@ -301,9 +301,9 @@ void EtherCAT_dev_link_state(ec_device_t *device, /**< EtherCAT-Ger /*****************************************************************************/ -EXPORT_SYMBOL(EtherCAT_dev_is_ec); -EXPORT_SYMBOL(EtherCAT_dev_receive); -EXPORT_SYMBOL(EtherCAT_dev_link_state); +EXPORT_SYMBOL(ecdev_is_ec); +EXPORT_SYMBOL(ecdev_receive); +EXPORT_SYMBOL(ecdev_link_state); /*****************************************************************************/ diff --git a/master/device.h b/master/device.h index 5888b148..a7f04861 100644 --- a/master/device.h +++ b/master/device.h @@ -13,12 +13,10 @@ #include <linux/interrupt.h> -#include "../include/EtherCAT_rt.h" -#include "../include/EtherCAT_dev.h" +#include "../include/ecrt.h" +#include "../devices/ecdev.h" #include "globals.h" -typedef irqreturn_t (*ec_isr_t)(int, void *, struct pt_regs *); - /*****************************************************************************/ /** diff --git a/master/domain.c b/master/domain.c index aad5f5c7..ac73d7e2 100644 --- a/master/domain.c +++ b/master/domain.c @@ -21,15 +21,10 @@ void ec_domain_clear_field_regs(ec_domain_t *); */ void ec_domain_init(ec_domain_t *domain, /**< Domäne */ - ec_master_t *master, /**< Zugehöriger Master */ - ec_domain_mode_t mode, /**< Synchron/Asynchron */ - unsigned int timeout_us /**< Timeout in Mikrosekunden */ + ec_master_t *master /**< Zugehöriger Master */ ) { domain->master = master; - domain->mode = mode; - domain->timeout_us = timeout_us; - domain->data = NULL; domain->data_size = 0; domain->commands = NULL; @@ -232,28 +227,27 @@ void ec_domain_response_count(ec_domain_t *domain, /**< Dom \return Zeiger auf den Slave bei Erfolg, sonst NULL */ -ec_slave_t *EtherCAT_rt_register_slave_field(ec_domain_t *domain, - /**< Domäne */ - const char *address, - /**< ASCII-Addresse des Slaves, - siehe ec_master_slave_address() - */ - const char *vendor_name, - /**< Herstellername */ - const char *product_name, - /**< Produktname */ - void **data_ptr, - /**< Adresse des Zeigers auf die - Prozessdaten */ - ec_field_type_t field_type, - /**< Typ des Datenfeldes */ - unsigned int field_index, - /**< Gibt an, ab welchem Feld mit - Typ \a field_type gezählt - werden soll. */ - unsigned int field_count - /**< Anzahl Felder selben Typs */ - ) +ec_slave_t *ecrt_domain_register_field(ec_domain_t *domain, + /**< Domäne */ + const char *address, + /**< ASCII-Addresse des Slaves, + siehe ec_master_slave_address() */ + const char *vendor_name, + /**< Herstellername */ + const char *product_name, + /**< Produktname */ + void **data_ptr, + /**< Adresse des Zeigers auf die + Prozessdaten */ + const char *field_name, + /**< Name des Datenfeldes */ + unsigned int field_index, + /**< Gibt an, ab welchem Feld mit + Typ \a field_type gezählt + werden soll. */ + unsigned int field_count + /**< Anzahl Felder selben Typs */ + ) { ec_slave_t *slave; const ec_slave_type_t *type; @@ -293,7 +287,7 @@ ec_slave_t *EtherCAT_rt_register_slave_field(ec_domain_t *domain, field_offset = 0; for (j = 0; sync->fields[j]; j++) { field = sync->fields[j]; - if (field->type == field_type) { + if (!strcmp(field->name, field_name)) { if (field_idx == field_index) { ec_domain_reg_field(domain, slave, sync, field_offset, data_ptr++); @@ -305,9 +299,9 @@ ec_slave_t *EtherCAT_rt_register_slave_field(ec_domain_t *domain, } } - EC_ERR("Slave %i (\"%s %s\") registration mismatch: Type %i, index %i," - " count %i.\n", slave->ring_position, vendor_name, product_name, - field_type, field_index, field_count); + EC_ERR("Slave %i (\"%s %s\") registration mismatch: Field \"%s\"," + " index %i, count %i.\n", slave->ring_position, vendor_name, + product_name, field_name, field_index, field_count); return NULL; } @@ -321,23 +315,21 @@ ec_slave_t *EtherCAT_rt_register_slave_field(ec_domain_t *domain, \return 0 bei Erfolg, sonst < 0 */ -int EtherCAT_rt_register_domain_fields(ec_domain_t *domain, - /**< Domäne */ - ec_field_init_t *fields - /**< Array mit Datenfeldern */ - ) +int ecrt_domain_register_field_list(ec_domain_t *domain, + /**< Domäne */ + ec_field_init_t *fields + /**< Array mit Datenfeldern */ + ) { ec_field_init_t *field; - for (field = fields; field->data; field++) { - if (!EtherCAT_rt_register_slave_field(domain, field->address, - field->vendor, field->product, - field->data, field->field_type, - field->field_index, - field->field_count)) { + for (field = fields; field->data_ptr; field++) + if (!ecrt_domain_register_field(domain, field->slave_address, + field->vendor_name, + field->product_name, field->data_ptr, + field->field_name, field->field_index, + field->field_count)) return -1; - } - } return 0; } @@ -348,7 +340,7 @@ int EtherCAT_rt_register_domain_fields(ec_domain_t *domain, Setzt Prozessdaten-Kommandos in die Warteschlange des Masters. */ -void EtherCAT_rt_domain_queue(ec_domain_t *domain /**< Domäne */) +void ecrt_domain_queue(ec_domain_t *domain /**< Domäne */) { unsigned int i; size_t size; @@ -372,7 +364,7 @@ void EtherCAT_rt_domain_queue(ec_domain_t *domain /**< Dom Verarbeitet empfangene Prozessdaten. */ -void EtherCAT_rt_domain_process(ec_domain_t *domain /**< Domäne */) +void ecrt_domain_process(ec_domain_t *domain /**< Domäne */) { unsigned int working_counter_sum, i; ec_command_t *command; @@ -402,10 +394,10 @@ void EtherCAT_rt_domain_process(ec_domain_t *domain /**< Dom /*****************************************************************************/ -EXPORT_SYMBOL(EtherCAT_rt_register_slave_field); -EXPORT_SYMBOL(EtherCAT_rt_register_domain_fields); -EXPORT_SYMBOL(EtherCAT_rt_domain_queue); -EXPORT_SYMBOL(EtherCAT_rt_domain_process); +EXPORT_SYMBOL(ecrt_domain_register_field); +EXPORT_SYMBOL(ecrt_domain_register_field_list); +EXPORT_SYMBOL(ecrt_domain_queue); +EXPORT_SYMBOL(ecrt_domain_process); /*****************************************************************************/ diff --git a/master/domain.h b/master/domain.h index bbd318f5..958936c4 100644 --- a/master/domain.h +++ b/master/domain.h @@ -50,8 +50,6 @@ struct ec_domain size_t data_size; /**< Größe der Prozessdaten */ ec_command_t *commands; /**< EtherCAT-Kommandos für die Prozessdaten */ unsigned int command_count; /**< Anzahl allozierter Kommandos */ - ec_domain_mode_t mode; - unsigned int timeout_us; /**< Timeout in Mikrosekunden. */ uint32_t base_address; /**< Logische Basisaddresse der Domain */ unsigned int response_count; /**< Anzahl antwortender Slaves */ struct list_head field_regs; /**< Liste der Datenfeldregistrierungen */ @@ -59,10 +57,8 @@ struct ec_domain /*****************************************************************************/ -void ec_domain_init(ec_domain_t *, ec_master_t *, ec_domain_mode_t, - unsigned int); +void ec_domain_init(ec_domain_t *, ec_master_t *); void ec_domain_clear(ec_domain_t *); - int ec_domain_alloc(ec_domain_t *, uint32_t); /*****************************************************************************/ diff --git a/master/master.c b/master/master.c index c79a5f9f..4212f59f 100644 --- a/master/master.c +++ b/master/master.c @@ -14,8 +14,7 @@ #include <linux/slab.h> #include <linux/delay.h> -#include "../include/EtherCAT_rt.h" -#include "../include/EtherCAT_si.h" +#include "../include/ecrt.h" #include "globals.h" #include "master.h" #include "slave.h" @@ -372,24 +371,27 @@ int ec_master_simple_io(ec_master_t *master, /**< EtherCAT-Master */ do { ec_master_queue_command(master, command); - EtherCAT_rt_master_xio(master); + ecrt_master_sync_io(master); if (command->state == EC_CMD_RECEIVED) { break; } else if (command->state == EC_CMD_TIMEOUT) { - EC_ERR("Simple IO TIMED OUT!\n"); + EC_ERR("Simple-IO TIMEOUT!\n"); return -1; } else if (command->state == EC_CMD_ERROR) { - EC_ERR("Simple IO command error!\n"); + EC_ERR("Simple-IO command error!\n"); return -1; } + + // Keine direkte Antwort. Dem Slave Zeit lassen... + udelay(10); } while (unlikely(!command->working_counter && --response_tries_left)); if (unlikely(!response_tries_left)) { - EC_ERR("No response in simple IO!\n"); + EC_ERR("No response in simple-IO!\n"); return -1; } @@ -653,18 +655,12 @@ void ec_fmmu_config(const ec_fmmu_t *fmmu, /**< Sync-Manager */ *****************************************************************************/ /** - Registriert eine neue Domäne. + Erstellt eine neue Domäne. \return Zeiger auf die Domäne bei Erfolg, sonst NULL. */ -ec_domain_t *EtherCAT_rt_master_register_domain(ec_master_t *master, - /**< Domäne */ - ec_domain_mode_t mode, - /**< Modus */ - unsigned int timeout_us - /**< Timeout */ - ) +ec_domain_t *ecrt_master_create_domain(ec_master_t *master /**< Master */) { ec_domain_t *domain; @@ -673,8 +669,7 @@ ec_domain_t *EtherCAT_rt_master_register_domain(ec_master_t *master, return NULL; } - ec_domain_init(domain, master, mode, timeout_us); - + ec_domain_init(domain, master); list_add_tail(&domain->list, &master->domains); return domain; @@ -692,7 +687,7 @@ ec_domain_t *EtherCAT_rt_master_register_domain(ec_master_t *master, \return 0 bei Erfolg, sonst < 0 */ -int EtherCAT_rt_master_activate(ec_master_t *master /**< EtherCAT-Master */) +int ecrt_master_activate(ec_master_t *master /**< EtherCAT-Master */) { unsigned int i, j; ec_slave_t *slave; @@ -817,11 +812,9 @@ int EtherCAT_rt_master_activate(ec_master_t *master /**< EtherCAT-Master */) /** Setzt alle Slaves zurück in den Init-Zustand. - - \return 0 bei Erfolg, sonst < 0 */ -int EtherCAT_rt_master_deactivate(ec_master_t *master /**< EtherCAT-Master */) +void ecrt_master_deactivate(ec_master_t *master /**< EtherCAT-Master */) { ec_slave_t *slave; unsigned int i; @@ -829,26 +822,18 @@ int EtherCAT_rt_master_deactivate(ec_master_t *master /**< EtherCAT-Master */) for (i = 0; i < master->slave_count; i++) { slave = master->slaves + i; - - // CRC-Zählerstände ausgeben ec_slave_check_crc(slave); - - if (unlikely(ec_slave_state_change(slave, EC_SLAVE_STATE_INIT) != 0)) - return -1; + ec_slave_state_change(slave, EC_SLAVE_STATE_INIT); } - - return 0; } /*****************************************************************************/ /** - Sendet und empfängt Kommandos. - - \return 0 bei Erfolg, sonst < 0 + Sendet und empfängt Kommandos synchron. */ -void EtherCAT_rt_master_xio(ec_master_t *master) +void ecrt_master_sync_io(ec_master_t *master) { ec_command_t *command, *next; unsigned int commands_sent; @@ -911,6 +896,69 @@ void EtherCAT_rt_master_xio(ec_master_t *master) /*****************************************************************************/ +/** + Sendet Kommandos asynchron. +*/ + +void ecrt_master_async_send(ec_master_t *master) +{ + ec_command_t *command, *next; + + ec_master_output_stats(master); + + if (unlikely(!master->device->link_state)) { + // Link DOWN, keines der Kommandos kann gesendet werden. + list_for_each_entry_safe(command, next, &master->commands, list) { + command->state = EC_CMD_ERROR; + list_del_init(&command->list); + } + + // Device-Zustand abfragen + ec_device_call_isr(master->device); + return; + } + + // Rahmen senden + ec_master_send_commands(master); +} + +/*****************************************************************************/ + +/** + Empfängt Kommandos asynchron. +*/ + +void ecrt_master_async_receive(ec_master_t *master) +{ + ec_command_t *command, *next; + + ec_master_output_stats(master); + + ec_device_call_isr(master->device); + + // Alle empfangenen Kommandos aus der Liste entfernen + list_for_each_entry_safe(command, next, &master->commands, list) + if (command->state == EC_CMD_RECEIVED) + list_del_init(&command->list); + + // Alle verbleibenden Kommandos entfernen. + list_for_each_entry_safe(command, next, &master->commands, list) { + switch (command->state) { + case EC_CMD_SENT: + case EC_CMD_QUEUED: + command->state = EC_CMD_TIMEOUT; + master->stats.timeouts++; + ec_master_output_stats(master); + break; + default: + break; + } + list_del_init(&command->list); + } +} + +/*****************************************************************************/ + /** Setzt die Debug-Ebene des Masters. @@ -920,11 +968,9 @@ void EtherCAT_rt_master_xio(ec_master_t *master) - 2: Komplette Frame-Inhalte */ -void EtherCAT_rt_master_debug(ec_master_t *master, - /**< EtherCAT-Master */ - int level - /**< Debug-Level */ - ) +void ecrt_master_debug(ec_master_t *master, /**< EtherCAT-Master */ + int level /**< Debug-Level */ + ) { if (level != master->debug_level) { master->debug_level = level; @@ -938,9 +984,7 @@ void EtherCAT_rt_master_debug(ec_master_t *master, Gibt alle Informationen zum Master aus. */ -void EtherCAT_rt_master_print(const ec_master_t *master - /**< EtherCAT-Master */ - ) +void ecrt_master_print(const ec_master_t *master /**< EtherCAT-Master */) { unsigned int i; @@ -952,12 +996,14 @@ void EtherCAT_rt_master_print(const ec_master_t *master /*****************************************************************************/ -EXPORT_SYMBOL(EtherCAT_rt_master_register_domain); -EXPORT_SYMBOL(EtherCAT_rt_master_activate); -EXPORT_SYMBOL(EtherCAT_rt_master_deactivate); -EXPORT_SYMBOL(EtherCAT_rt_master_xio); -EXPORT_SYMBOL(EtherCAT_rt_master_debug); -EXPORT_SYMBOL(EtherCAT_rt_master_print); +EXPORT_SYMBOL(ecrt_master_create_domain); +EXPORT_SYMBOL(ecrt_master_activate); +EXPORT_SYMBOL(ecrt_master_deactivate); +EXPORT_SYMBOL(ecrt_master_sync_io); +EXPORT_SYMBOL(ecrt_master_async_send); +EXPORT_SYMBOL(ecrt_master_async_receive); +EXPORT_SYMBOL(ecrt_master_debug); +EXPORT_SYMBOL(ecrt_master_print); /*****************************************************************************/ diff --git a/master/module.c b/master/module.c index d1883e0e..1df08aee 100644 --- a/master/module.c +++ b/master/module.c @@ -145,16 +145,15 @@ void __exit ec_cleanup_module(void) oder das Geraet nicht geöffnet werden konnte. */ -ec_device_t *EtherCAT_dev_register(unsigned int master_index, - /**< Index des EtherCAT-Masters */ - struct net_device *net_dev, - /**< net_device des EtherCAT-Gerätes */ - irqreturn_t (*isr)(int, void *, - struct pt_regs *), - /**< Interrupt-Service-Routine */ - struct module *module - /**< Zeiger auf das Modul */ - ) +ec_device_t *ecdev_register(unsigned int master_index, + /**< Index des EtherCAT-Masters */ + struct net_device *net_dev, + /**< net_device des EtherCAT-Gerätes */ + ec_isr_t isr, + /**< Interrupt-Service-Routine */ + struct module *module + /**< Zeiger auf das Modul */ + ) { ec_master_t *master; @@ -193,11 +192,11 @@ ec_device_t *EtherCAT_dev_register(unsigned int master_index, Hebt die Registrierung eines EtherCAT-Gerätes auf. */ -void EtherCAT_dev_unregister(unsigned int master_index, - /**< Index des EtherCAT-Masters */ - ec_device_t *device - /**< EtherCAT-Geraet */ - ) +void ecdev_unregister(unsigned int master_index, + /**< Index des EtherCAT-Masters */ + ec_device_t *device + /**< EtherCAT-Geraet */ + ) { ec_master_t *master; @@ -232,9 +231,9 @@ void EtherCAT_dev_unregister(unsigned int master_index, \return Zeiger auf EtherCAT-Master oder NULL, wenn Parameter ungueltig. */ -ec_master_t *EtherCAT_rt_request_master(unsigned int index - /**< EtherCAT-Master-Index */ - ) +ec_master_t *ecrt_request_master(unsigned int index + /**< EtherCAT-Master-Index */ + ) { ec_master_t *master; @@ -297,7 +296,7 @@ ec_master_t *EtherCAT_rt_request_master(unsigned int index Gibt einen zuvor angeforderten EtherCAT-Master wieder frei. */ -void EtherCAT_rt_release_master(ec_master_t *master /**< EtherCAT-Masdter */) +void ecrt_release_master(ec_master_t *master /**< EtherCAT-Masdter */) { unsigned int i, found; @@ -331,10 +330,10 @@ void EtherCAT_rt_release_master(ec_master_t *master /**< EtherCAT-Masdter */) 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); +EXPORT_SYMBOL(ecdev_register); +EXPORT_SYMBOL(ecdev_unregister); +EXPORT_SYMBOL(ecrt_request_master); +EXPORT_SYMBOL(ecrt_release_master); /*****************************************************************************/ diff --git a/master/slave.c b/master/slave.c index 326d349d..98d95457 100644 --- a/master/slave.c +++ b/master/slave.c @@ -11,7 +11,6 @@ #include <linux/module.h> #include <linux/delay.h> -#include "../include/EtherCAT_si.h" #include "globals.h" #include "slave.h" #include "command.h" diff --git a/master/types.c b/master/types.c index 20264924..d2731f26 100644 --- a/master/types.c +++ b/master/types.c @@ -38,7 +38,7 @@ const ec_slave_type_t Beckhoff_EK1110 = { /*****************************************************************************/ -const ec_field_t el1014_in = {ec_ipvalue, 1}; +const ec_field_t el1014_in = {"InputValue", 1}; const ec_sync_t el1014_sm0 = { // Inputs 0x1000, 1, 0x00, @@ -52,7 +52,7 @@ const ec_slave_type_t Beckhoff_EL1014 = { /*****************************************************************************/ -const ec_field_t el20XX_out = {ec_opvalue, 1}; +const ec_field_t el20XX_out = {"OutputValue", 1}; const ec_sync_t el20XX_sm0 = { 0x0F00, 1, 0x46, @@ -71,10 +71,10 @@ const ec_slave_type_t Beckhoff_EL2032 = { /*****************************************************************************/ -const ec_field_t el31X2_st1 = {ec_status, 1}; -const ec_field_t el31X2_ip1 = {ec_ipvalue, 2}; -const ec_field_t el31X2_st2 = {ec_status, 1}; -const ec_field_t el31X2_ip2 = {ec_ipvalue, 2}; +const ec_field_t el31X2_st1 = {"Status", 1}; +const ec_field_t el31X2_ip1 = {"InputValue", 2}; +const ec_field_t el31X2_st2 = {"Status", 1}; +const ec_field_t el31X2_ip2 = {"InputValue", 2}; const ec_sync_t el31X2_sm2 = { 0x1000, 4, 0x24, @@ -98,7 +98,7 @@ const ec_slave_type_t Beckhoff_EL3162 = { /*****************************************************************************/ -const ec_field_t el41X2_op = {ec_opvalue, 2}; +const ec_field_t el41X2_op = {"OutputValue", 2}; const ec_sync_t el41X2_sm2 = { 0x1000, 4, 0x24, @@ -117,8 +117,8 @@ const ec_slave_type_t Beckhoff_EL4132 = { /*****************************************************************************/ -const ec_field_t el5001_st = {ec_status, 1}; -const ec_field_t el5001_ip = {ec_ipvalue, 4}; +const ec_field_t el5001_st = {"Status", 1}; +const ec_field_t el5001_ip = {"InputValue", 4}; const ec_sync_t el5001_sm2 = { 0x1000, 4, 0x24, @@ -137,11 +137,11 @@ const ec_slave_type_t Beckhoff_EL5001 = { /*****************************************************************************/ -const ec_field_t el5101_ct = {ec_control, 1}; -const ec_field_t el5101_op = {ec_opvalue, 2}; -const ec_field_t el5101_st = {ec_status, 1}; -const ec_field_t el5101_ip = {ec_ipvalue, 2}; -const ec_field_t el5101_la = {ec_ipvalue, 2}; +const ec_field_t el5101_ct = {"Control", 1}; +const ec_field_t el5101_op = {"OutputValue", 2}; +const ec_field_t el5101_st = {"Status", 1}; +const ec_field_t el5101_ip = {"InputValue", 2}; +const ec_field_t el5101_la = {"LatchValue", 2}; const ec_sync_t el5101_sm2 = { 0x1000, 3, 0x24, diff --git a/master/types.h b/master/types.h index f6d9f9bf..0b2b9639 100644 --- a/master/types.h +++ b/master/types.h @@ -13,7 +13,7 @@ #include <linux/types.h> -#include "../include/EtherCAT_rt.h" +#include "../include/ecrt.h" /*****************************************************************************/ @@ -28,8 +28,8 @@ typedef struct { - ec_field_type_t type; - unsigned int size; + const char *name; + size_t size; } ec_field_t; diff --git a/mini/mini.c b/mini/mini.c index c03acbc0..71fdee6e 100644 --- a/mini/mini.c +++ b/mini/mini.c @@ -12,8 +12,9 @@ #include <linux/delay.h> #include <linux/timer.h> -#include "../include/EtherCAT_rt.h" // Echtzeitschnittstelle -#include "../include/EtherCAT_si.h" // Slave-Interface-Makros +#include "../include/ecrt.h" // Echtzeitschnittstelle + +//#define ASYNC /*****************************************************************************/ @@ -29,14 +30,12 @@ ec_domain_t *domain1 = NULL; // Datenfelder void *r_ssi; -void *r_inc; // Kanäle -uint32_t k_angle, k_pos; +uint32_t k_pos; ec_field_init_t domain1_fields[] = { - {&r_ssi, "1", "Beckhoff", "EL5001", ec_ipvalue, 0, 1}, - {&r_inc, "0:3", "Beckhoff", "EL5101", ec_ipvalue, 0, 1}, + {&r_ssi, "1", "Beckhoff", "EL5001", "InputValue", 0, 1}, {} }; @@ -46,20 +45,32 @@ void run(unsigned long data) { static unsigned int counter = 0; - // Prozessdaten lesen und schreiben - EtherCAT_rt_domain_queue(domain1); - EtherCAT_rt_master_xio(master); - EtherCAT_rt_domain_process(domain1); +#ifdef ASYNC + // Prozessdaten emfpangen + ecrt_master_async_receive(master); + ecrt_domain_process(domain1); + + // Prozessdaten verarbeiten + k_pos = EC_READ_U32(r_ssi); + + // Prozessdaten senden + ecrt_domain_queue(domain1); + ecrt_master_async_send(master); +#else + // Prozessdaten senden und emfpangen + ecrt_domain_queue(domain1); + ecrt_master_sync_io(master); + ecrt_domain_process(domain1); - k_angle = EC_READ_U16(r_inc); + // Prozessdaten verarbeiten k_pos = EC_READ_U32(r_ssi); +#endif if (counter) { counter--; } else { counter = ABTASTFREQUENZ; - printk(KERN_INFO "k_angle = %i\n", k_angle); printk(KERN_INFO "k_pos = %i\n", k_pos); } @@ -72,20 +83,18 @@ void run(unsigned long data) int __init init_mini_module(void) { - const ec_field_init_t *field; - printk(KERN_INFO "=== Starting Minimal EtherCAT environment... ===\n"); - if ((master = EtherCAT_rt_request_master(0)) == NULL) { + if ((master = ecrt_request_master(0)) == NULL) { printk(KERN_ERR "Error requesting master 0!\n"); goto out_return; } - EtherCAT_rt_master_print(master); + //ecrt_master_print(master); printk(KERN_INFO "Registering domain...\n"); - if (!(domain1 = EtherCAT_rt_master_register_domain(master, ec_sync, 100))) + if (!(domain1 = ecrt_master_create_domain(master))) { printk(KERN_ERR "EtherCAT: Could not register domain!\n"); goto out_release_master; @@ -93,28 +102,24 @@ int __init init_mini_module(void) printk(KERN_INFO "Registering domain fields...\n"); - for (field = domain1_fields; field->data; field++) - { - if (!EtherCAT_rt_register_slave_field(domain1, - field->address, - field->vendor, - field->product, - field->data, - field->field_type, - field->field_index, - field->field_count)) { - printk(KERN_ERR "EtherCAT: Could not register field!\n"); - goto out_release_master; - } + if (ecrt_domain_register_field_list(domain1, domain1_fields)) { + printk(KERN_ERR "EtherCAT: Could not register field!\n"); + goto out_release_master; } printk(KERN_INFO "Activating master...\n"); - if (EtherCAT_rt_master_activate(master)) { + if (ecrt_master_activate(master)) { printk(KERN_ERR "EtherCAT: Could not activate master!\n"); goto out_release_master; } +#ifdef ASYNC + ecrt_domain_queue(domain1); + ecrt_master_async_send(master); + udelay(100); +#endif + printk("Starting cyclic sample thread.\n"); init_timer(&timer); @@ -127,7 +132,7 @@ int __init init_mini_module(void) return 0; out_release_master: - EtherCAT_rt_release_master(master); + ecrt_release_master(master); out_return: return -1; @@ -145,8 +150,8 @@ void __exit cleanup_mini_module(void) printk(KERN_INFO "Deactivating master...\n"); - EtherCAT_rt_master_deactivate(master); - EtherCAT_rt_release_master(master); + ecrt_master_deactivate(master); + ecrt_release_master(master); } printk(KERN_INFO "=== Minimal EtherCAT environment stopped. ===\n"); diff --git a/rt/msr_module.c b/rt/msr_module.c index a03ded14..3872f224 100644 --- a/rt/msr_module.c +++ b/rt/msr_module.c @@ -23,6 +23,7 @@ #include <linux/ipipe.h> #include <linux/slab.h> #include <linux/vmalloc.h> +#include <linux/delay.h> // RT_lib #include <msr_main.h> @@ -34,8 +35,9 @@ #include "msr_param.h" // EtherCAT -#include "../include/EtherCAT_rt.h" -#include "../include/EtherCAT_si.h" +#include "../include/ecrt.h" + +//#define ASYNC // Defines/Makros #define HZREDUCTION (MSR_ABTASTFREQUENZ / HZ) @@ -59,14 +61,17 @@ void *r_inc; uint32_t k_angle; uint32_t k_pos; +uint32_t k_preio; +uint32_t k_postio; +uint32_t k_finished; ec_field_init_t domain1_fields[] = { - {&r_ssi, "1", "Beckhoff", "EL5001", ec_ipvalue, 0, 1}, + {&r_ssi, "1", "Beckhoff", "EL5001", "InputValue", 0, 1}, {} }; ec_field_init_t domain2_fields[] = { - {&r_ssi2, "1", "Beckhoff", "EL5001", ec_ipvalue, 0, 1}, + {&r_ssi2, "1", "Beckhoff", "EL5001", "InputValue", 0, 1}, {} }; @@ -74,27 +79,48 @@ ec_field_init_t domain2_fields[] = { static void msr_controller_run(void) { + cycles_t offset; static unsigned int counter = 0; + offset = get_cycles(); + if (counter) counter--; else { //EtherCAT_rt_master_debug(master, 2); counter = MSR_ABTASTFREQUENZ; } - // Prozessdaten lesen und schreiben - EtherCAT_rt_domain_queue(domain1); - EtherCAT_rt_domain_queue(domain2); + k_preio = (uint32_t) (get_cycles() - offset) * 1e6 / cpu_khz; - EtherCAT_rt_master_xio(master); +#ifdef ASYNC + // Empfangen + ecrt_master_async_receive(master); + ecrt_domain_process(domain1); + ecrt_domain_process(domain2); - EtherCAT_rt_domain_process(domain1); - EtherCAT_rt_domain_process(domain2); + // Prozessdaten verarbeiten + k_pos = EC_READ_U32(r_ssi); - //k_angle = EC_READ_U16(r_inc); + // Senden + ecrt_domain_queue(domain1); + ecrt_domain_queue(domain2); + ecrt_master_async_send(master); +#else + // Senden und empfangen + ecrt_domain_queue(domain1); + ecrt_domain_queue(domain2); + ecrt_master_sync_io(master); + ecrt_domain_process(domain1); + ecrt_domain_process(domain2); + + // Prozessdaten verarbeiten k_pos = EC_READ_U32(r_ssi); +#endif + + k_postio = (uint32_t) (get_cycles() - offset) * 1e6 / cpu_khz; - //EtherCAT_rt_master_debug(master, 0); + //ecrt_master_debug(master, 0); + k_finished = (uint32_t) (get_cycles() - offset) * 1e6 / cpu_khz; } /*****************************************************************************/ @@ -104,6 +130,10 @@ int msr_globals_register(void) msr_reg_kanal("/angle0", "", &k_angle, TUINT); msr_reg_kanal("/pos0", "", &k_pos, TUINT); + msr_reg_kanal("/Timing/Pre-IO", "ns", &k_preio, TUINT); + msr_reg_kanal("/Timing/Post-IO", "ns", &k_postio, TUINT); + msr_reg_kanal("/Timing/Finished", "ns", &k_finished, TUINT); + return 0; } @@ -148,59 +178,63 @@ int __init init_rt_module(void) goto out_return; } - if ((master = EtherCAT_rt_request_master(0)) == NULL) { + if ((master = ecrt_request_master(0)) == NULL) { printk(KERN_ERR "Error requesting master 0!\n"); goto out_msr_cleanup; } - //EtherCAT_rt_master_print(master); + //ecrt_master_print(master); printk(KERN_INFO "Registering domains...\n"); - if (!(domain1 = EtherCAT_rt_master_register_domain(master, ec_sync, 100))) - { + if (!(domain1 = ecrt_master_create_domain(master))) { printk(KERN_ERR "EtherCAT: Could not register domain!\n"); goto out_release_master; } - if (!(domain2 = EtherCAT_rt_master_register_domain(master, ec_sync, 100))) - { + if (!(domain2 = ecrt_master_create_domain(master))) { printk(KERN_ERR "EtherCAT: Could not register domain!\n"); goto out_release_master; } printk(KERN_INFO "Registering domain fields...\n"); - if (EtherCAT_rt_register_domain_fields(domain1, domain1_fields)) { + if (ecrt_domain_register_field_list(domain1, domain1_fields)) { printk(KERN_ERR "Failed to register domain fields.\n"); goto out_release_master; } - if (EtherCAT_rt_register_domain_fields(domain2, domain2_fields)) { + if (ecrt_domain_register_field_list(domain2, domain2_fields)) { printk(KERN_ERR "Failed to register domain fields.\n"); goto out_release_master; } printk(KERN_INFO "Activating master...\n"); - //EtherCAT_rt_master_debug(master, 2); + //ecrt_master_debug(master, 2); - if (EtherCAT_rt_master_activate(master)) { + if (ecrt_master_activate(master)) { printk(KERN_ERR "Could not activate master!\n"); goto out_release_master; } - //EtherCAT_rt_master_debug(master, 0); + //ecrt_master_debug(master, 0); #if 1 - if (EtherCAT_rt_canopen_sdo_addr_read(master, "6", 0x100A, 1, - &version)) { + if (ecrt_master_sdo_read(master, "6", 0x100A, 1, &version)) { printk(KERN_ERR "Could not read SSI version!\n"); goto out_release_master; } printk(KERN_INFO "Software-version: %u\n", version); #endif +#ifdef ASYNC + ecrt_domain_queue(domain1); + ecrt_domain_queue(domain2); + ecrt_master_async_send(master); + udelay(100); +#endif + ipipe_init_attr(&attr); attr.name = "IPIPE-MSR-MODULE"; attr.priority = IPIPE_ROOT_PRIO + 1; @@ -210,7 +244,7 @@ int __init init_rt_module(void) return 0; out_release_master: - EtherCAT_rt_release_master(master); + ecrt_release_master(master); out_msr_cleanup: msr_rtlib_cleanup(); @@ -233,12 +267,8 @@ void __exit cleanup_rt_module(void) printk(KERN_INFO "=== Stopping EtherCAT environment... ===\n"); printk(KERN_INFO "Deactivating master...\n"); - - if (EtherCAT_rt_master_deactivate(master) < 0) { - printk(KERN_WARNING "Warning - Could not deactivate master!\n"); - } - - EtherCAT_rt_release_master(master); + ecrt_master_deactivate(master); + ecrt_release_master(master); printk(KERN_INFO "=== EtherCAT environment stopped. ===\n"); } -- GitLab