# HG changeset patch # User Florian Pose # Date 1145539891 0 # Node ID 674071846ee3a901590755a9e84a4975f12e767b # Parent c21e7c12dd5028bfe3c2e7722b2d138cb562c499 Translated all comments and documentation to english language. diff -r c21e7c12dd50 -r 674071846ee3 Makefile --- a/Makefile Thu Apr 20 13:19:36 2006 +0000 +++ b/Makefile Thu Apr 20 13:31:31 2006 +0000 @@ -9,7 +9,7 @@ ifneq ($(KERNELRELEASE),) #------------------------------------------------------------------------------ -# kbuild section +# kbuild section obj-m := master/ devices/ @@ -18,7 +18,7 @@ else #------------------------------------------------------------------------------ -# default section +# default section ifneq ($(wildcard ethercat.conf),) include ethercat.conf diff -r c21e7c12dd50 -r 674071846ee3 devices/8139too.c --- a/devices/8139too.c Thu Apr 20 13:19:36 2006 +0000 +++ b/devices/8139too.c Thu Apr 20 13:31:31 2006 +0000 @@ -2,14 +2,15 @@ * * 8 1 3 9 t o o . c * - * EtherCAT-Treiber für RTL8139-kompatible Netzwerkkarten. + * EtherCAT driver for RTL8139-compatible NICs. * - * Autoren: Wilhelm Hagemeister, Florian Pose + * Authors: Florian Pose + * Wilhelm Hagemeister * * $Date$ * $Author$ * - * (C) Copyright IgH 2005 + * (C) Copyright IgH 2006 * Ingenieurgemeinschaft IgH * Heinz-Bäcker Str. 34 * D-45356 Essen @@ -112,7 +113,6 @@ #define DRV_NAME "8139too_ec" #define DRV_VERSION "0.9.27" - #include #include #include @@ -644,8 +644,10 @@ /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ -MODULE_AUTHOR ("Wilhelm Hagemeister , Florian Pose "); -MODULE_DESCRIPTION ("RealTek RTL-8139 Fast Ethernet driver with EtherCAT functionality"); +MODULE_AUTHOR("Wilhelm Hagemeister ," + " Florian Pose "); +MODULE_DESCRIPTION("RealTek RTL-8139 Fast Ethernet" + " driver with EtherCAT functionality"); MODULE_LICENSE("GPL"); MODULE_VERSION(COMPILE_INFO); @@ -664,8 +666,10 @@ module_param(ec_device_index, int, -1); module_param(ec_device_master_index, int, 0); -MODULE_PARM_DESC(ec_device_index, "Index of the device reserved for EtherCAT."); -MODULE_PARM_DESC(ec_device_master_index, "Index of the EtherCAT master to register the device."); +MODULE_PARM_DESC(ec_device_index, + "Index of the device reserved for EtherCAT."); +MODULE_PARM_DESC(ec_device_master_index, + "Index of the EtherCAT master to register the device."); /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ @@ -1082,12 +1086,11 @@ /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ - /* EtherCAT-Karten nicht beim Stack anmelden. */ - if (dev != rtl_ec_net_dev) - { - DPRINTK("About to register device named %s (%p)...\n", dev->name, dev); - i = register_netdev (dev); - if (i) goto err_out; + if (dev != rtl_ec_net_dev) { + DPRINTK("About to register device named %s (%p)...\n", + dev->name, dev); + i = register_netdev (dev); + if (i) goto err_out; } /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ @@ -1181,9 +1184,8 @@ /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ - if (dev != rtl_ec_net_dev) - { - unregister_netdev (dev); + if (dev != rtl_ec_net_dev) { + unregister_netdev (dev); } /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ @@ -1394,11 +1396,11 @@ printk(KERN_DEBUG "%s: open\n", dev->name); #endif - if (dev != rtl_ec_net_dev) - { - retval = request_irq(dev->irq, rtl8139_interrupt, SA_SHIRQ, dev->name, dev); - if (retval) - return retval; + if (dev != rtl_ec_net_dev) { + retval = request_irq(dev->irq, rtl8139_interrupt, + SA_SHIRQ, dev->name, dev); + if (retval) + return retval; } /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ @@ -1411,9 +1413,8 @@ { /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ - if (dev != rtl_ec_net_dev) - { - free_irq(dev->irq, dev); + if (dev != rtl_ec_net_dev) { + free_irq(dev->irq, dev); } /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ @@ -1436,20 +1437,18 @@ /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ - if (dev != rtl_ec_net_dev) - { - netif_start_queue (dev); - - if (netif_msg_ifup(tp)) - { - printk(KERN_DEBUG "%s: rtl8139_open() ioaddr %#lx IRQ %d" - " GP Pins %2.2x %s-duplex.\n", - dev->name, pci_resource_start (tp->pci_dev, 1), - dev->irq, RTL_R8 (MediaStatus), - tp->mii.full_duplex ? "full" : "half"); - } - - rtl8139_start_thread(dev); + if (dev != rtl_ec_net_dev) { + netif_start_queue (dev); + + if (netif_msg_ifup(tp)) { + printk(KERN_DEBUG "%s: rtl8139_open() ioaddr %#lx IRQ %d" + " GP Pins %2.2x %s-duplex.\n", + dev->name, pci_resource_start (tp->pci_dev, 1), + dev->irq, RTL_R8 (MediaStatus), + tp->mii.full_duplex ? "full" : "half"); + } + + rtl8139_start_thread(dev); } /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ @@ -1536,10 +1535,9 @@ /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ - if (dev != rtl_ec_net_dev) - { - /* Enable all known interrupts by setting the interrupt mask. */ - RTL_W16 (IntrMask, rtl8139_intr_mask); + if (dev != rtl_ec_net_dev) { + /* Enable all known interrupts by setting the interrupt mask. */ + RTL_W16 (IntrMask, rtl8139_intr_mask); } /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ @@ -1805,32 +1803,29 @@ /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ - if (dev != rtl_ec_net_dev) - { - spin_lock(&tp->rx_lock); - - /* Disable interrupts by clearing the interrupt mask. */ - RTL_W16 (IntrMask, 0x0000); - - /* Stop a shared interrupt from scavenging while we are. */ - spin_lock_irqsave (&tp->lock, flags); - rtl8139_tx_clear (tp); - spin_unlock_irqrestore (&tp->lock, flags); - - /* ...and finally, reset everything */ - - if (netif_running(dev)) - { - rtl8139_hw_start (dev); - netif_wake_queue (dev); - } - - spin_unlock(&tp->rx_lock); + if (dev != rtl_ec_net_dev) { + spin_lock(&tp->rx_lock); + + /* Disable interrupts by clearing the interrupt mask. */ + RTL_W16 (IntrMask, 0x0000); + + /* Stop a shared interrupt from scavenging while we are. */ + spin_lock_irqsave (&tp->lock, flags); + rtl8139_tx_clear (tp); + spin_unlock_irqrestore (&tp->lock, flags); + + /* ...and finally, reset everything */ + + if (netif_running(dev)) { + rtl8139_hw_start (dev); + netif_wake_queue (dev); + } + + spin_unlock(&tp->rx_lock); } - else - { - rtl8139_tx_clear (tp); - rtl8139_hw_start(dev); + else { + rtl8139_tx_clear (tp); + rtl8139_hw_start(dev); } /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ @@ -1864,9 +1859,8 @@ return 0; } - if (dev != rtl_ec_net_dev) - { - spin_lock_irq(&tp->lock); + if (dev != rtl_ec_net_dev) { + spin_lock_irq(&tp->lock); } /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ @@ -1881,8 +1875,7 @@ /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ - if (dev != rtl_ec_net_dev) - { + if (dev != rtl_ec_net_dev) { if ((tp->cur_tx - NUM_TX_DESC) == tp->dirty_tx) netif_stop_queue (dev); @@ -1972,9 +1965,8 @@ /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ - if (dev != rtl_ec_net_dev) - { - netif_wake_queue (dev); + if (dev != rtl_ec_net_dev) { + netif_wake_queue (dev); } /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ @@ -2184,42 +2176,41 @@ /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ - if (dev != rtl_ec_net_dev) - { - /* Malloc up new buffer, compatible with net-2e. */ - /* Omit the four octet CRC from the length. */ - skb = dev_alloc_skb(pkt_size + 2); - - if (likely(skb)) { - skb->dev = dev; - skb_reserve (skb, 2); /* 16 byte align the IP fields. */ + if (dev != rtl_ec_net_dev) { + /* Malloc up new buffer, compatible with net-2e. */ + /* Omit the four octet CRC from the length. */ + skb = dev_alloc_skb(pkt_size + 2); + + if (likely(skb)) { + skb->dev = dev; + skb_reserve (skb, 2); /* 16 byte align the IP fields. */ #if RX_BUF_IDX == 3 - wrap_copy(skb, rx_ring, ring_offset+4, pkt_size); + wrap_copy(skb, rx_ring, ring_offset+4, pkt_size); #else - eth_copy_and_sum (skb, &rx_ring[ring_offset + 4], pkt_size, 0); + eth_copy_and_sum (skb, &rx_ring[ring_offset + 4], pkt_size, 0); #endif - skb_put (skb, pkt_size); - - skb->protocol = eth_type_trans (skb, dev); - - dev->last_rx = jiffies; - tp->stats.rx_bytes += pkt_size; - tp->stats.rx_packets++; - - netif_receive_skb (skb); - } else { - if (net_ratelimit()) - printk (KERN_WARNING - "%s: Memory squeeze, dropping packet.\n", - dev->name); - tp->stats.rx_dropped++; - } + skb_put (skb, pkt_size); + + skb->protocol = eth_type_trans (skb, dev); + + dev->last_rx = jiffies; + tp->stats.rx_bytes += pkt_size; + tp->stats.rx_packets++; + + netif_receive_skb (skb); + } else { + if (net_ratelimit()) + printk (KERN_WARNING + "%s: Memory squeeze, dropping packet.\n", + dev->name); + tp->stats.rx_dropped++; + } } else { ecdev_receive(rtl_ec_dev, - &rx_ring[ring_offset + 4] + ETH_HLEN, - pkt_size - ETH_HLEN); + &rx_ring[ring_offset + 4] + ETH_HLEN, + pkt_size - ETH_HLEN); dev->last_rx = jiffies; tp->stats.rx_bytes += pkt_size; tp->stats.rx_packets++; @@ -2347,18 +2338,16 @@ /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ - if (dev == rtl_ec_net_dev) - { - status = RTL_R16 (IntrStatus); - } - else - { - spin_lock(&tp->lock); - - status = RTL_R16 (IntrStatus); - - if (unlikely((status & rtl8139_intr_mask) == 0)) - goto out; + if (dev == rtl_ec_net_dev) { + status = RTL_R16 (IntrStatus); + } + else { + spin_lock(&tp->lock); + + status = RTL_R16 (IntrStatus); + + if (unlikely((status & rtl8139_intr_mask) == 0)) + goto out; } /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ @@ -2371,13 +2360,12 @@ /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ - if (dev != rtl_ec_net_dev) - { - /* close possible race's with dev_close */ - if (unlikely(!netif_running(dev))) { - RTL_W16 (IntrMask, 0); - goto out; - } + if (dev != rtl_ec_net_dev) { + /* close possible race's with dev_close */ + if (unlikely(!netif_running(dev))) { + RTL_W16 (IntrMask, 0); + goto out; + } } /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ @@ -2399,19 +2387,17 @@ if (status & RxAckBits) { - if (dev != rtl_ec_net_dev) - { - /* Polling vormerken */ - if (netif_rx_schedule_prep(dev)) { - RTL_W16_F (IntrMask, rtl8139_norx_intr_mask); - __netif_rx_schedule (dev); + if (dev != rtl_ec_net_dev) { + /* Mark for polling */ + if (netif_rx_schedule_prep(dev)) { + RTL_W16_F (IntrMask, rtl8139_norx_intr_mask); + __netif_rx_schedule (dev); + } } - } - else - { - /* Beim EtherCAT-Device einfach alle Frames empfangen */ - rtl8139_rx(dev, tp, 100); // FIXME - } + else { + /* EtherCAT device: Just receive all frames */ + rtl8139_rx(dev, tp, 100); // FIXME + } } /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ @@ -2429,9 +2415,8 @@ out: /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ - if (dev != rtl_ec_net_dev) - { - spin_unlock (&tp->lock); + if (dev != rtl_ec_net_dev) { + spin_unlock (&tp->lock); } /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ @@ -2463,52 +2448,50 @@ /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ - if (dev != rtl_ec_net_dev) - { - netif_stop_queue(dev); - if (tp->thr_pid >= 0) { - tp->time_to_die = 1; - wmb(); - ret = kill_proc (tp->thr_pid, SIGTERM, 1); - if (ret) { - printk (KERN_ERR "%s: unable to signal thread\n", dev->name); - return ret; - } - wait_for_completion (&tp->thr_exited); + if (dev != rtl_ec_net_dev) { + netif_stop_queue(dev); + if (tp->thr_pid >= 0) { + tp->time_to_die = 1; + wmb(); + ret = kill_proc (tp->thr_pid, SIGTERM, 1); + if (ret) { + printk (KERN_ERR "%s: unable to signal thread\n", dev->name); + return ret; } - - if (netif_msg_ifdown(tp)) - printk(KERN_DEBUG "%s: Shutting down ethercard, status was 0x%4.4x.\n", - dev->name, RTL_R16 (IntrStatus)); - - spin_lock_irqsave (&tp->lock, flags); - - /* Stop the chip's Tx and Rx DMA processes. */ - RTL_W8 (ChipCmd, 0); - - /* Disable interrupts by clearing the interrupt mask. */ - RTL_W16 (IntrMask, 0); - - /* Update the error counts. */ - tp->stats.rx_missed_errors += RTL_R32 (RxMissed); - RTL_W32 (RxMissed, 0); - - spin_unlock_irqrestore (&tp->lock, flags); - - synchronize_irq (dev->irq); /* racy, but that's ok here */ - free_irq (dev->irq, dev); + wait_for_completion (&tp->thr_exited); + } + + if (netif_msg_ifdown(tp)) + printk(KERN_DEBUG "%s: Shutting down ethercard, status was 0x%4.4x.\n", + dev->name, RTL_R16 (IntrStatus)); + + spin_lock_irqsave (&tp->lock, flags); + + /* Stop the chip's Tx and Rx DMA processes. */ + RTL_W8 (ChipCmd, 0); + + /* Disable interrupts by clearing the interrupt mask. */ + RTL_W16 (IntrMask, 0); + + /* Update the error counts. */ + tp->stats.rx_missed_errors += RTL_R32 (RxMissed); + RTL_W32 (RxMissed, 0); + + spin_unlock_irqrestore (&tp->lock, flags); + + synchronize_irq (dev->irq); /* racy, but that's ok here */ + free_irq (dev->irq, dev); } - else - { - /* Stop the chip's Tx and Rx DMA processes. */ - RTL_W8 (ChipCmd, 0); - - /* Disable interrupts by clearing the interrupt mask. */ - RTL_W16 (IntrMask, 0); - - /* Update the error counts. */ - tp->stats.rx_missed_errors += RTL_R32 (RxMissed); - RTL_W32 (RxMissed, 0); + else { + /* Stop the chip's Tx and Rx DMA processes. */ + RTL_W8 (ChipCmd, 0); + + /* Disable interrupts by clearing the interrupt mask. */ + RTL_W16 (IntrMask, 0); + + /* Update the error counts. */ + tp->stats.rx_missed_errors += RTL_R32 (RxMissed); + RTL_W32 (RxMissed, 0); } /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ @@ -2729,7 +2712,7 @@ /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ if (dev == rtl_ec_net_dev || !netif_running(dev)) - return -EINVAL; + return -EINVAL; /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ @@ -2749,12 +2732,11 @@ /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ - if (dev == rtl_ec_net_dev || netif_running(dev)) - { - spin_lock_irqsave (&tp->lock, flags); - tp->stats.rx_missed_errors += RTL_R32 (RxMissed); - RTL_W32 (RxMissed, 0); - spin_unlock_irqrestore (&tp->lock, flags); + if (dev == rtl_ec_net_dev || netif_running(dev)) { + spin_lock_irqsave (&tp->lock, flags); + tp->stats.rx_missed_errors += RTL_R32 (RxMissed); + RTL_W32 (RxMissed, 0); + spin_unlock_irqrestore (&tp->lock, flags); } /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ @@ -2837,7 +2819,7 @@ /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ if (dev == rtl_ec_net_dev || !netif_running (dev)) - return 0; + return 0; /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ @@ -2870,7 +2852,7 @@ /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ if (dev == rtl_ec_net_dev || !netif_running (dev)) - return 0; + return 0; /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ @@ -2942,23 +2924,23 @@ static void __exit rtl8139_cleanup_module (void) { - /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ - - printk(KERN_INFO "Cleaning up RTL8139-EtherCAT module...\n"); - - if (rtl_ec_net_dev) { - printk(KERN_INFO "Stopping device...\n"); - ecdev_stop(ec_device_master_index); - printk(KERN_INFO "Unregistering device...\n"); - ecdev_unregister(ec_device_master_index, rtl_ec_dev); - rtl_ec_dev = NULL; - } - - pci_unregister_driver(&rtl8139_pci_driver); - - printk(KERN_INFO "RTL8139-EtherCAT module cleaned up.\n"); - - /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ + /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ + + printk(KERN_INFO "Cleaning up RTL8139-EtherCAT module...\n"); + + if (rtl_ec_net_dev) { + printk(KERN_INFO "Stopping device...\n"); + ecdev_stop(ec_device_master_index); + printk(KERN_INFO "Unregistering device...\n"); + ecdev_unregister(ec_device_master_index, rtl_ec_dev); + rtl_ec_dev = NULL; + } + + pci_unregister_driver(&rtl8139_pci_driver); + + printk(KERN_INFO "RTL8139-EtherCAT module cleaned up.\n"); + + /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ } diff -r c21e7c12dd50 -r 674071846ee3 devices/ecdev.h --- a/devices/ecdev.h Thu Apr 20 13:19:36 2006 +0000 +++ b/devices/ecdev.h Thu Apr 20 13:31:31 2006 +0000 @@ -1,8 +1,8 @@ /****************************************************************************** * - * Oeffentliche EtherCAT-Schnittstellen fuer EtherCAT-Geraetetreiber. + * EtherCAT interface for EtherCAT device drivers. * - * $Id$ + * $Id$ * *****************************************************************************/ diff -r c21e7c12dd50 -r 674071846ee3 include/ecrt.h --- a/include/ecrt.h Thu Apr 20 13:19:36 2006 +0000 +++ b/include/ecrt.h Thu Apr 20 13:31:31 2006 +0000 @@ -1,6 +1,6 @@ /****************************************************************************** * - * Oeffentliche EtherCAT-Schnittstellen fuer Echtzeitprozesse. + * EtherCAT realtime interface. * * $Id$ * diff -r c21e7c12dd50 -r 674071846ee3 master/canopen.c --- a/master/canopen.c Thu Apr 20 13:19:36 2006 +0000 +++ b/master/canopen.c Thu Apr 20 13:31:31 2006 +0000 @@ -28,14 +28,14 @@ /*****************************************************************************/ /** - Liest 32 Bit eines CANopen-SDOs im Expedited-Modus aus einem Slave. - \return 0 wenn alles ok, < 0 bei Fehler - */ - -int ec_slave_sdo_read_exp(ec_slave_t *slave, /**< EtherCAT-Slave */ - uint16_t sdo_index, /**< SDO-Index */ - uint8_t sdo_subindex, /**< SDO-Subindex */ - uint8_t *target /**< Speicher für 4 Bytes */ + Reads 32 bit of a CANopen SDO in expedited mode. + \return 0 in case of success, else < 0 + */ + +int ec_slave_sdo_read_exp(ec_slave_t *slave, /**< EtherCAT slave */ + uint16_t sdo_index, /**< SDO index */ + uint8_t sdo_subindex, /**< SDO subindex */ + uint8_t *target /**< 4-byte memory */ ) { size_t rec_size; @@ -45,14 +45,14 @@ EC_WRITE_U16(data, 0x2 << 12); // SDO request EC_WRITE_U8 (data + 2, (0x1 << 1 // expedited transfer - | 0x2 << 5)); // initiate upload request + | 0x2 << 5)); // initiate upload request EC_WRITE_U16(data + 3, sdo_index); EC_WRITE_U8 (data + 5, sdo_subindex); if (!(data = ec_slave_mbox_simple_io(slave, &rec_size))) return -1; if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request - EC_READ_U8 (data + 2) >> 5 == 0x4) { // Abort SDO transfer request + EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request EC_ERR("SDO upload 0x%04X:%X aborted on slave %i.\n", sdo_index, sdo_subindex, slave->ring_position); ec_canopen_abort_msg(EC_READ_U32(data + 6)); @@ -60,9 +60,9 @@ } if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response - EC_READ_U8 (data + 2) >> 5 != 0x2 || // Upload response - EC_READ_U16(data + 3) != sdo_index || // Index - EC_READ_U8 (data + 5) != sdo_subindex) { // Subindex + EC_READ_U8 (data + 2) >> 5 != 0x2 || // upload response + EC_READ_U16(data + 3) != sdo_index || // index + EC_READ_U8 (data + 5) != sdo_subindex) { // subindex EC_ERR("SDO upload 0x%04X:%X failed:\n", sdo_index, sdo_subindex); EC_ERR("Invalid SDO upload response at slave %i!\n", slave->ring_position); @@ -77,14 +77,14 @@ /*****************************************************************************/ /** - Beschreibt ein CANopen-SDO eines Slaves im Expedited-Modus. - \return 0 wenn alles ok, < 0 bei Fehler - */ - -int ec_slave_sdo_write_exp(ec_slave_t *slave, /**< EtherCAT-Slave */ - uint16_t sdo_index, /**< SDO-Index */ - uint8_t sdo_subindex, /**< SDO-Subindex */ - const uint8_t *sdo_data, /**< Neuer Wert */ + Writes a CANopen SDO using expedited mode. + \return 0 in case of success, else < 0 + */ + +int ec_slave_sdo_write_exp(ec_slave_t *slave, /**< EtherCAT slave */ + uint16_t sdo_index, /**< SDO index */ + uint8_t sdo_subindex, /**< SDO subindex */ + const uint8_t *sdo_data, /**< new value */ size_t size ) { @@ -111,7 +111,7 @@ if (!(data = ec_slave_mbox_simple_io(slave, &rec_size))) return -1; if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request - EC_READ_U8 (data + 2) >> 5 == 0x4) { // Abort SDO transfer request + EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request EC_ERR("SDO download 0x%04X:%X (%i bytes) aborted on slave %i.\n", sdo_index, sdo_subindex, size, slave->ring_position); ec_canopen_abort_msg(EC_READ_U32(data + 6)); @@ -119,9 +119,9 @@ } if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response - EC_READ_U8 (data + 2) >> 5 != 0x3 || // Download response - EC_READ_U16(data + 3) != sdo_index || // Index - EC_READ_U8 (data + 5) != sdo_subindex) { // Subindex + EC_READ_U8 (data + 2) >> 5 != 0x3 || // download response + EC_READ_U16(data + 3) != sdo_index || // index + EC_READ_U8 (data + 5) != sdo_subindex) { // subindex EC_ERR("SDO download 0x%04X:%X (%i bytes) failed:\n", sdo_index, sdo_subindex, size); EC_ERR("Invalid SDO download response at slave %i!\n", @@ -136,15 +136,17 @@ /*****************************************************************************/ /** - Liest ein CANopen-SDO im "Normal-Modus" aus einem Slave. - \return 0 wenn alles ok, < 0 bei Fehler - */ - -int ecrt_slave_sdo_read(ec_slave_t *slave, /**< EtherCAT-Slave */ - uint16_t sdo_index, /**< SDO-Index */ - uint8_t sdo_subindex, /**< SDO-Subindex */ - uint8_t *target, /**< Speicher für gel. Wert */ - size_t *size /**< Größe des Speichers */ + Reads a CANopen SDO in normal mode. + \return 0 in case of success, else < 0 + + \todo size + */ + +int ecrt_slave_sdo_read(ec_slave_t *slave, /**< EtherCAT slave */ + uint16_t sdo_index, /**< SDO index */ + uint8_t sdo_subindex, /**< SDO subindex */ + uint8_t *target, /**< memory for value */ + size_t *size /**< target memory size */ ) { uint8_t *data; @@ -161,7 +163,7 @@ if (!(data = ec_slave_mbox_simple_io(slave, &rec_size))) return -1; if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request - EC_READ_U8 (data + 2) >> 5 == 0x4) { // Abort SDO transfer request + EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request EC_ERR("SDO upload 0x%04X:%X aborted on slave %i.\n", sdo_index, sdo_subindex, slave->ring_position); ec_canopen_abort_msg(EC_READ_U32(data + 6)); @@ -169,9 +171,9 @@ } if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response - EC_READ_U8 (data + 2) >> 5 != 0x2 || // Initiate upload response - EC_READ_U16(data + 3) != sdo_index || // Index - EC_READ_U8 (data + 5) != sdo_subindex) { // Subindex + EC_READ_U8 (data + 2) >> 5 != 0x2 || // initiate upload response + EC_READ_U16(data + 3) != sdo_index || // index + EC_READ_U8 (data + 5) != sdo_subindex) { // subindex EC_ERR("SDO upload 0x%04X:%X failed:\n", sdo_index, sdo_subindex); EC_ERR("Invalid SDO upload response at slave %i!\n", slave->ring_position); @@ -205,11 +207,11 @@ /*****************************************************************************/ /** - Lädt das gesamte SDO-Dictionary aus einem Slave. - \return 0, wenn alles ok, sonst < 0 + Fetches the SDO dictionary of a slave. + \return 0 in case of success, else < 0 */ -int ec_slave_fetch_sdo_list(ec_slave_t *slave /**< EtherCAT-Slave */) +int ec_slave_fetch_sdo_list(ec_slave_t *slave /**< EtherCAT slave */) { uint8_t *data; size_t rec_size; @@ -223,7 +225,7 @@ EC_WRITE_U8 (data + 2, 0x01); // Get OD List Request EC_WRITE_U8 (data + 3, 0x00); EC_WRITE_U16(data + 4, 0x0000); - EC_WRITE_U16(data + 6, 0x0001); // Deliver all SDOs! + EC_WRITE_U16(data + 6, 0x0001); // deliver all SDOs! if (unlikely(ec_master_simple_io(slave->master, &slave->mbox_command))) { EC_ERR("Mailbox checking failed on slave %i!\n", slave->ring_position); @@ -235,7 +237,7 @@ return -1; if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information - (EC_READ_U8(data + 2) & 0x7F) == 0x07) { // Error response + (EC_READ_U8(data + 2) & 0x7F) == 0x07) { // error response EC_ERR("SDO information error response at slave %i!\n", slave->ring_position); ec_canopen_abort_msg(EC_READ_U32(data + 6)); @@ -259,7 +261,7 @@ sdo_count = (rec_size - 8) / 2; for (i = 0; i < sdo_count; i++) { sdo_index = EC_READ_U16(data + 8 + i * 2); - if (!sdo_index) continue; // Manchmal ist der Index 0... ??? + if (!sdo_index) continue; // sometimes index is 0... ??? if (!(sdo = (ec_sdo_t *) kmalloc(sizeof(ec_sdo_t), GFP_KERNEL))) { EC_ERR("Failed to allocate memory for SDO!\n"); @@ -278,7 +280,7 @@ } while (EC_READ_U8(data + 2) & 0x80); - // Alle Beschreibungen laden + // Fetch all SDO descriptions if (ec_slave_fetch_sdo_descriptions(slave)) return -1; return 0; @@ -287,11 +289,11 @@ /*****************************************************************************/ /** - Holt die Beschreibungen zu allen bereits bekannten SDOs. - \return 0, wenn alles ok, sonst < 0 + Fetches the SDO descriptions for the known SDOs. + \return 0 in case of success, else < 0 */ -int ec_slave_fetch_sdo_descriptions(ec_slave_t *slave /**< EtherCAT-Slave */) +int ec_slave_fetch_sdo_descriptions(ec_slave_t *slave /**< EtherCAT slave */) { uint8_t *data; size_t rec_size, name_size; @@ -308,7 +310,7 @@ if (!(data = ec_slave_mbox_simple_io(slave, &rec_size))) return -1; if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information - (EC_READ_U8 (data + 2) & 0x7F) == 0x07) { // Error response + (EC_READ_U8 (data + 2) & 0x7F) == 0x07) { // error response EC_ERR("SDO information error response at slave %i while" " fetching SDO 0x%04X!\n", slave->ring_position, sdo->index); @@ -354,7 +356,7 @@ return -1; } - // Alle Entries (Subindizes) laden + // Fetch all entries (subindices) if (ec_slave_fetch_sdo_entries(slave, sdo, EC_READ_U8(data + 10))) return -1; } @@ -365,13 +367,13 @@ /*****************************************************************************/ /** - Lädt alle Entries (Subindizes) zu einem SDO. - \return 0, wenn alles ok, sonst < 0 + Fetches all entries (subindices) to an SDO. + \return 0 in case of success, else < 0 */ -int ec_slave_fetch_sdo_entries(ec_slave_t *slave, /**< EtherCAT-Slave */ +int ec_slave_fetch_sdo_entries(ec_slave_t *slave, /**< EtherCAT slave */ ec_sdo_t *sdo, /**< SDO */ - uint8_t subindices /**< Anzahl Subindizes */ + uint8_t subindices /**< number of subindices */ ) { uint8_t *data; @@ -394,7 +396,7 @@ if (!(data = ec_slave_mbox_simple_io(slave, &rec_size))) return -1; if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information - (EC_READ_U8 (data + 2) & 0x7F) == 0x07) { // Error response + (EC_READ_U8 (data + 2) & 0x7F) == 0x07) { // error response EC_ERR("SDO information error response at slave %i while" " fetching SDO entry 0x%04X:%i!\n", slave->ring_position, sdo->index, i); @@ -403,7 +405,7 @@ } if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information - (EC_READ_U8(data + 2) & 0x7F) != 0x06 || // entry descr. response + (EC_READ_U8(data + 2) & 0x7F) != 0x06 || // Entry desc. response EC_READ_U16(data + 6) != sdo->index || // SDO index EC_READ_U8(data + 8) != i) { // SDO subindex EC_ERR("Invalid entry description response at slave %i while" @@ -449,7 +451,7 @@ /*****************************************************************************/ /** - Gibt eine SDO-Abort-Meldung aus. + Outputs an SDO abort message. */ void ec_canopen_abort_msg(uint32_t abort_code) @@ -506,21 +508,20 @@ {} }; -/*****************************************************************************/ -// Echtzeitschnittstelle - -/*****************************************************************************/ - -/** - Liest ein 8-Bit CANopen-SDO im Expedited-Modus aus einem Slave. - Siehe ec_slave_sdo_read_exp() - \return 0 wenn alles ok, < 0 bei Fehler - */ - -int ecrt_slave_sdo_read_exp8(ec_slave_t *slave, /**< EtherCAT-Slave */ - uint16_t sdo_index, /**< SDO-Index */ - uint8_t sdo_subindex, /**< SDO-Subindex */ - uint8_t *target /**< Speicher für gel. Wert */ +/****************************************************************************** + * Realtime interface + *****************************************************************************/ + +/** + Reads an 8-bit SDO in expedited mode. + See ec_slave_sdo_read_exp() + \return 0 in case of success, else < 0 + */ + +int ecrt_slave_sdo_read_exp8(ec_slave_t *slave, /**< EtherCAT slave */ + uint16_t sdo_index, /**< SDO index */ + uint8_t sdo_subindex, /**< SDO subindex */ + uint8_t *target /**< memory for read value */ ) { uint8_t data[4]; @@ -532,15 +533,15 @@ /*****************************************************************************/ /** - Liest ein 16-Bit CANopen-SDO im Expedited-Modus aus einem Slave. - Siehe ec_slave_sdo_read_exp() - \return 0 wenn alles ok, < 0 bei Fehler - */ - -int ecrt_slave_sdo_read_exp16(ec_slave_t *slave, /**< EtherCAT-Slave */ - uint16_t sdo_index, /**< SDO-Index */ - uint8_t sdo_subindex, /**< SDO-Subindex */ - uint16_t *target /**< Speicher für gel. Wert */ + Reads a 16-bit SDO in expedited mode. + See ec_slave_sdo_read_exp() + \return 0 in case of success, else < 0 + */ + +int ecrt_slave_sdo_read_exp16(ec_slave_t *slave, /**< EtherCAT slave */ + uint16_t sdo_index, /**< SDO index */ + uint8_t sdo_subindex, /**< SDO subindex */ + uint16_t *target /**< memory for read value */ ) { uint8_t data[4]; @@ -552,15 +553,15 @@ /*****************************************************************************/ /** - Liest ein 32-Bit CANopen-SDO im Expedited-Modus aus einem Slave. - Siehe ec_slave_sdo_read_exp() - \return 0 wenn alles ok, < 0 bei Fehler - */ - -int ecrt_slave_sdo_read_exp32(ec_slave_t *slave, /**< EtherCAT-Slave */ - uint16_t sdo_index, /**< SDO-Index */ - uint8_t sdo_subindex, /**< SDO-Subindex */ - uint32_t *target /**< Speicher für gel. Wert */ + Reads a 32-bit SDO in expedited mode. + See ec_slave_sdo_read_exp() + \return 0 in case of success, else < 0 + */ + +int ecrt_slave_sdo_read_exp32(ec_slave_t *slave, /**< EtherCAT slave */ + uint16_t sdo_index, /**< SDO index */ + uint8_t sdo_subindex, /**< SDO subindex */ + uint32_t *target /**< memory for read value */ ) { uint8_t data[4]; @@ -572,14 +573,14 @@ /*****************************************************************************/ /** - Beschreibt ein 8-Bit CANopen-SDO eines Slaves im Expedited-Modus. - \return 0 wenn alles ok, < 0 bei Fehler - */ - -int ecrt_slave_sdo_write_exp8(ec_slave_t *slave, /**< EtherCAT-Slave */ - uint16_t sdo_index, /**< SDO-Index */ - uint8_t sdo_subindex, /**< SDO-Subindex */ - uint8_t value /**< Neuer Wert */ + Writes an 8-bit SDO in expedited mode. + \return 0 in case of success, else < 0 + */ + +int ecrt_slave_sdo_write_exp8(ec_slave_t *slave, /**< EtherCAT slave */ + uint16_t sdo_index, /**< SDO index */ + uint8_t sdo_subindex, /**< SDO subindex */ + uint8_t value /**< new value */ ) { return ec_slave_sdo_write_exp(slave, sdo_index, sdo_subindex, &value, 1); @@ -588,14 +589,14 @@ /*****************************************************************************/ /** - Beschreibt ein 16-Bit CANopen-SDO eines Slaves im Expedited-Modus. - \return 0 wenn alles ok, < 0 bei Fehler - */ - -int ecrt_slave_sdo_write_exp16(ec_slave_t *slave, /**< EtherCAT-Slave */ - uint16_t sdo_index, /**< SDO-Index */ - uint8_t sdo_subindex, /**< SDO-Subindex */ - uint16_t value /**< Neuer Wert */ + Writes a 16-bit SDO in expedited mode. + \return 0 in case of success, else < 0 + */ + +int ecrt_slave_sdo_write_exp16(ec_slave_t *slave, /**< EtherCAT slave */ + uint16_t sdo_index, /**< SDO index */ + uint8_t sdo_subindex, /**< SDO subindex */ + uint16_t value /**< new value */ ) { uint8_t data[2]; @@ -606,14 +607,14 @@ /*****************************************************************************/ /** - Beschreibt ein 32-Bit CANopen-SDO eines Slaves im Expedited-Modus. - \return 0 wenn alles ok, < 0 bei Fehler - */ - -int ecrt_slave_sdo_write_exp32(ec_slave_t *slave, /**< EtherCAT-Slave */ - uint16_t sdo_index, /**< SDO-Index */ - uint8_t sdo_subindex, /**< SDO-Subindex */ - uint32_t value /**< Neuer Wert */ + Writes a 32-bit SDO in expedited mode. + \return 0 in case of success, else < 0 + */ + +int ecrt_slave_sdo_write_exp32(ec_slave_t *slave, /**< EtherCAT slave */ + uint16_t sdo_index, /**< SDO index */ + uint8_t sdo_subindex, /**< SDO subindex */ + uint32_t value /**< new value */ ) { uint8_t data[4]; @@ -632,9 +633,3 @@ EXPORT_SYMBOL(ecrt_slave_sdo_read); /*****************************************************************************/ - -/* Emacs-Konfiguration -;;; Local Variables: *** -;;; c-basic-offset:4 *** -;;; End: *** -*/ diff -r c21e7c12dd50 -r 674071846ee3 master/command.c --- a/master/command.c Thu Apr 20 13:19:36 2006 +0000 +++ b/master/command.c Thu Apr 20 13:31:31 2006 +0000 @@ -2,7 +2,7 @@ * * c o m m a n d . c * - * Methoden für ein EtherCAT-Kommando. + * Methods of an EtherCAT command. * * $Id$ * @@ -31,7 +31,7 @@ /*****************************************************************************/ /** - EtherCAT-Kommando-Konstruktor. + Command constructor. */ void ec_command_init(ec_command_t *command) @@ -49,7 +49,7 @@ /*****************************************************************************/ /** - EtherCAT-Kommando-Destruktor. + Command destructor. */ void ec_command_clear(ec_command_t *command) @@ -60,7 +60,8 @@ /*****************************************************************************/ /** - Alloziert Speicher. + Allocates command data memory. + \return 0 in case of success, else < 0 */ int ec_command_prealloc(ec_command_t *command, size_t size) @@ -85,19 +86,19 @@ /*****************************************************************************/ /** - Initialisiert ein EtherCAT-NPRD-Kommando. - + Initializes an EtherCAT NPRD command. Node-adressed physical read. + \return 0 in case of success, else < 0 */ int ec_command_nprd(ec_command_t *command, - /**< EtherCAT-Rahmen */ + /**< EtherCAT command */ uint16_t node_address, - /**< Adresse des Knotens (Slaves) */ - uint16_t offset, - /**< Physikalische Speicheradresse im Slave */ - size_t data_size - /**< Länge der zu lesenden Daten */ + /**< configured station address */ + uint16_t offset, + /**< physical memory address */ + size_t data_size + /**< number of bytes to read */ ) { if (unlikely(node_address == 0x0000)) @@ -113,19 +114,19 @@ /*****************************************************************************/ /** - Initialisiert ein EtherCAT-NPWR-Kommando. - + Initializes an EtherCAT NPWR command. Node-adressed physical write. + \return 0 in case of success, else < 0 */ int ec_command_npwr(ec_command_t *command, - /**< EtherCAT-Rahmen */ + /**< EtherCAT command */ uint16_t node_address, - /**< Adresse des Knotens (Slaves) */ - uint16_t offset, - /**< Physikalische Speicheradresse im Slave */ - size_t data_size - /**< Länge der zu schreibenden Daten */ + /**< configured station address */ + uint16_t offset, + /**< physical memory address */ + size_t data_size + /**< number of bytes to write */ ) { if (unlikely(node_address == 0x0000)) @@ -141,19 +142,19 @@ /*****************************************************************************/ /** - Initialisiert ein EtherCAT-APRD-Kommando. - + Initializes an EtherCAT APRD command. Autoincrement physical read. + \return 0 in case of success, else < 0 */ int ec_command_aprd(ec_command_t *command, - /**< EtherCAT-Rahmen */ + /**< EtherCAT command */ uint16_t ring_position, - /**< Position des Slaves im Bus */ - uint16_t offset, - /**< Physikalische Speicheradresse im Slave */ - size_t data_size - /**< Länge der zu lesenden Daten */ + /**< auto-increment position */ + uint16_t offset, + /**< physical memory address */ + size_t data_size + /**< number of bytes to read */ ) { EC_FUNC_HEADER; @@ -166,19 +167,19 @@ /*****************************************************************************/ /** - Initialisiert ein EtherCAT-APWR-Kommando. - + Initializes an EtherCAT APWR command. Autoincrement physical write. + \return 0 in case of success, else < 0 */ int ec_command_apwr(ec_command_t *command, - /**< EtherCAT-Rahmen */ + /**< EtherCAT command */ uint16_t ring_position, - /**< Position des Slaves im Bus */ - uint16_t offset, - /**< Physikalische Speicheradresse im Slave */ - size_t data_size - /**< Länge der zu schreibenden Daten */ + /**< auto-increment position */ + uint16_t offset, + /**< physical memory address */ + size_t data_size + /**< number of bytes to write */ ) { EC_FUNC_HEADER; @@ -191,17 +192,17 @@ /*****************************************************************************/ /** - Initialisiert ein EtherCAT-BRD-Kommando. - + Initializes an EtherCAT BRD command. Broadcast read. + \return 0 in case of success, else < 0 */ int ec_command_brd(ec_command_t *command, - /**< EtherCAT-Rahmen */ + /**< EtherCAT command */ uint16_t offset, - /**< Physikalische Speicheradresse im Slave */ + /**< physical memory address */ size_t data_size - /**< Länge der zu lesenden Daten */ + /**< number of bytes to read */ ) { EC_FUNC_HEADER; @@ -214,17 +215,17 @@ /*****************************************************************************/ /** - Initialisiert ein EtherCAT-BWR-Kommando. - + Initializes an EtherCAT BWR command. Broadcast write. + \return 0 in case of success, else < 0 */ int ec_command_bwr(ec_command_t *command, - /**< EtherCAT-Rahmen */ + /**< EtherCAT command */ uint16_t offset, - /**< Physikalische Speicheradresse im Slave */ + /**< physical memory address */ size_t data_size - /**< Länge der zu schreibenden Daten */ + /**< number of bytes to write */ ) { EC_FUNC_HEADER; @@ -237,17 +238,17 @@ /*****************************************************************************/ /** - Initialisiert ein EtherCAT-LRW-Kommando. - + Initializes an EtherCAT LRW command. Logical read write. + \return 0 in case of success, else < 0 */ int ec_command_lrw(ec_command_t *command, - /**< EtherCAT-Rahmen */ + /**< EtherCAT command */ uint32_t offset, - /**< Logische Startadresse */ + /**< logical address */ size_t data_size - /**< Länge der zu lesenden/schreibenden Daten */ + /**< number of bytes to read/write */ ) { EC_FUNC_HEADER; @@ -257,9 +258,3 @@ } /*****************************************************************************/ - -/* Emacs-Konfiguration -;;; Local Variables: *** -;;; c-basic-offset:4 *** -;;; End: *** -*/ diff -r c21e7c12dd50 -r 674071846ee3 master/command.h --- a/master/command.h Thu Apr 20 13:19:36 2006 +0000 +++ b/master/command.h Thu Apr 20 13:31:31 2006 +0000 @@ -2,7 +2,7 @@ * * c o m m a n d . h * - * Struktur für ein EtherCAT-Kommando. + * EtherCAT command structure. * * $Id$ * @@ -18,7 +18,7 @@ /*****************************************************************************/ /** - EtherCAT-Kommando-Typ. + EtherCAT command type. */ typedef enum @@ -35,65 +35,57 @@ ec_command_type_t; /** - EtherCAT-Kommando-Zustand. + EtherCAT command state. */ typedef enum { - EC_CMD_INIT, /**< Neues Kommando */ - EC_CMD_QUEUED, /**< Kommando in Warteschlange */ - EC_CMD_SENT, /**< Kommando gesendet */ - EC_CMD_RECEIVED, /**< Kommando empfangen */ - EC_CMD_TIMEOUT, /**< Zeitgrenze überschritten */ - EC_CMD_ERROR /**< Fehler beim Senden oder Empfangen */ + EC_CMD_INIT, /**< new command */ + EC_CMD_QUEUED, /**< command queued by master */ + EC_CMD_SENT, /**< command has been sent */ + EC_CMD_RECEIVED, /**< command has been received */ + EC_CMD_TIMEOUT, /**< command timed out */ + EC_CMD_ERROR /**< error while sending/receiving */ } ec_command_state_t; /*****************************************************************************/ /** - EtherCAT-Adresse. - - Im EtherCAT-Kommando sind 4 Bytes für die Adresse reserviert, die je nach - Kommandotyp, eine andere Bedeutung haben können: Bei Autoinkrementbefehlen - 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. + EtherCAT address. */ typedef union { struct { - uint16_t slave; /**< Adresse des Slaves (Ringposition oder Knoten) */ - uint16_t mem; /**< Physikalische Speicheradresse im Slave */ + uint16_t slave; /**< configured or autoincrement address */ + uint16_t mem; /**< physical memory address */ } - physical; /**< Physikalische Adresse */ + physical; /**< physical address */ - uint32_t logical; /**< Logische Adresse */ + uint32_t logical; /**< logical address */ } ec_address_t; /*****************************************************************************/ /** - EtherCAT-Kommando. + EtherCAT command */ typedef struct { - struct list_head list; /**< Kommando-Listeneintrag */ - struct list_head queue; /**< Master-Kommando-Queue */ - ec_command_type_t type; /**< Typ des Kommandos (APRD, NPWR, etc) */ - ec_address_t address; /**< Adresse des/der Empfänger */ - uint8_t *data; /**< Kommandodaten */ - size_t mem_size; /**< Größe des Speichers */ - size_t data_size; /**< Länge der zu sendenden und/oder empfangenen Daten */ - uint8_t index; /**< Kommando-Index, wird vom Master beim Senden gesetzt. */ - uint16_t working_counter; /**< Working-Counter */ - ec_command_state_t state; /**< Zustand */ + struct list_head list; /**< needed by domain command lists */ + struct list_head queue; /**< master command queue item */ + ec_command_type_t type; /**< command type (APRD, BWR, etc) */ + ec_address_t address; /**< receipient address */ + uint8_t *data; /**< command data */ + size_t mem_size; /**< command \a data memory size */ + size_t data_size; /**< size of the data in \a data */ + uint8_t index; /**< command index (set by master) */ + uint16_t working_counter; /**< working counter */ + ec_command_state_t state; /**< command state */ } ec_command_t; @@ -113,9 +105,3 @@ /*****************************************************************************/ #endif - -/* Emacs-Konfiguration -;;; Local Variables: *** -;;; c-basic-offset:4 *** -;;; End: *** -*/ diff -r c21e7c12dd50 -r 674071846ee3 master/device.c --- a/master/device.c Thu Apr 20 13:19:36 2006 +0000 +++ b/master/device.c Thu Apr 20 13:31:31 2006 +0000 @@ -2,7 +2,7 @@ * * d e v i c e . c * - * Methoden für ein EtherCAT-Gerät. + * EtherCAT device methods. * * $Id$ * @@ -20,16 +20,15 @@ /*****************************************************************************/ /** - EtherCAT-Geräte-Konstuktor. - - \return 0 wenn alles ok, < 0 bei Fehler (zu wenig Speicher) -*/ - -int ec_device_init(ec_device_t *device, /**< EtherCAT-Gerät */ - ec_master_t *master, /**< Zugehöriger Master */ - struct net_device *net_dev, /**< Net-Device */ - ec_isr_t isr, /**< Adresse der ISR */ - struct module *module /**< Modul-Adresse */ + Device constructor. + \return 0 in case of success, else < 0 +*/ + +int ec_device_init(ec_device_t *device, /**< EtherCAT device */ + ec_master_t *master, /**< master owning the device */ + struct net_device *net_dev, /**< net_device structure */ + ec_isr_t isr, /**< pointer to device's ISR */ + struct module *module /**< pointer to the owning module */ ) { struct ethhdr *eth; @@ -49,7 +48,7 @@ device->tx_skb->dev = net_dev; - // Ethernet-II-Header hinzufuegen + // add Ethernet-II-header skb_reserve(device->tx_skb, ETH_HLEN); eth = (struct ethhdr *) skb_push(device->tx_skb, ETH_HLEN); eth->h_proto = htons(0x88A4); @@ -62,13 +61,10 @@ /*****************************************************************************/ /** - EtherCAT-Geräte-Destuktor. - - Gibt den dynamisch allozierten Speicher des - EtherCAT-Gerätes (den Sende-Socket-Buffer) wieder frei. -*/ - -void ec_device_clear(ec_device_t *device /**< EtherCAT-Gerät */) + EtherCAT device destuctor. +*/ + +void ec_device_clear(ec_device_t *device /**< EtherCAT device */) { if (device->open) ec_device_close(device); if (device->tx_skb) dev_kfree_skb(device->tx_skb); @@ -77,17 +73,11 @@ /*****************************************************************************/ /** - Führt die open()-Funktion des Netzwerktreibers aus. - - Dies entspricht einem "ifconfig up". Vorher wird der Zeiger - auf das EtherCAT-Gerät auf Gültigkeit geprüft und der - Gerätezustand zurückgesetzt. - - \return 0 bei Erfolg, < 0: Ungültiger Zeiger, oder open() - fehlgeschlagen -*/ - -int ec_device_open(ec_device_t *device /**< EtherCAT-Gerät */) + Opens the EtherCAT device. + \return 0 in case of success, else < 0 +*/ + +int ec_device_open(ec_device_t *device /**< EtherCAT device */) { unsigned int i; @@ -101,7 +91,7 @@ return 0; } - // Device could have received frames before + // device could have received frames before for (i = 0; i < 4; i++) ec_device_call_isr(device); device->link_state = 0; @@ -114,13 +104,11 @@ /*****************************************************************************/ /** - Führt die stop()-Funktion des net_devices aus. - - \return 0 bei Erfolg, < 0: Kein Gerät zum Schließen oder - Schließen fehlgeschlagen. -*/ - -int ec_device_close(ec_device_t *device /**< EtherCAT-Gerät */) + Stops the EtherCAT device. + \return 0 in case of success, else < 0 +*/ + +int ec_device_close(ec_device_t *device /**< EtherCAT device */) { if (!device->dev) { EC_ERR("No device to close!\n"); @@ -140,12 +128,11 @@ /*****************************************************************************/ /** - Liefert einen Zeiger auf den Sende-Speicher. - - \return Zeiger auf den Speicher, in den die Frame-Daten sollen. -*/ - -uint8_t *ec_device_tx_data(ec_device_t *device /**< EtherCAT-Gerät */) + Returns a pointer to the device's transmit memory. + \return pointer to the TX socket buffer +*/ + +uint8_t *ec_device_tx_data(ec_device_t *device /**< EtherCAT device */) { return device->tx_skb->data + ETH_HLEN; } @@ -153,21 +140,19 @@ /*****************************************************************************/ /** - Sendet den Inhalt des Socket-Buffers. - - Schneidet den Inhalt des Socket-Buffers auf die (nun bekannte) Größe zu, - fügt den Ethernet-II-Header an und ruft die start_xmit()-Funktion der - Netzwerkkarte auf. -*/ - -void ec_device_send(ec_device_t *device, /**< EtherCAT-Gerät */ - size_t size /**< Größe der zu sendenden Daten */ + Sends the content of the transmit socket buffer. + Cuts the socket buffer content to the (now known) size, and calls the + start_xmit() function of the assigned net_device. +*/ + +void ec_device_send(ec_device_t *device, /**< EtherCAT device */ + size_t size /**< number of bytes to send */ ) { if (unlikely(!device->link_state)) // Link down return; - // Framegröße auf (jetzt bekannte) Länge abschneiden + // set the right length for the data device->tx_skb->len = ETH_HLEN + size; if (unlikely(device->master->debug_level > 1)) { @@ -175,36 +160,33 @@ ec_print_data(device->tx_skb->data + ETH_HLEN, size); } - // Senden einleiten + // start sending device->dev->hard_start_xmit(device->tx_skb, device->dev); } /*****************************************************************************/ /** - Ruft die Interrupt-Routine der Netzwerkkarte auf. -*/ - -void ec_device_call_isr(ec_device_t *device /**< EtherCAT-Gerät */) + Calls the interrupt service routine of the assigned net_device. +*/ + +void ec_device_call_isr(ec_device_t *device /**< EtherCAT device */) { if (likely(device->isr)) device->isr(0, device->dev, NULL); } /****************************************************************************** - * - * Treiberschnittstelle - * + * Device interface *****************************************************************************/ /** - Nimmt einen Empfangenen Rahmen entgegen. - - Kopiert die empfangenen Daten in den Receive-Buffer. -*/ - -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 */ + Accepts a received frame. + Forwards the received data to the master. +*/ + +void ecdev_receive(ec_device_t *device, /**< EtherCAT device */ + const void *data, /**< pointer to receibed data */ + size_t size /**< number of bytes received */ ) { if (unlikely(device->master->debug_level > 1)) { @@ -218,11 +200,11 @@ /*****************************************************************************/ /** - Setzt einen neuen Verbindungszustand. -*/ - -void ecdev_link_state(ec_device_t *device, /**< EtherCAT-Gerät */ - uint8_t state /**< Verbindungszustand */ + Sets a new link state. +*/ + +void ecdev_link_state(ec_device_t *device, /**< EtherCAT device */ + uint8_t state /**< new link state */ ) { if (unlikely(!device)) { @@ -242,9 +224,3 @@ EXPORT_SYMBOL(ecdev_link_state); /*****************************************************************************/ - -/* Emacs-Konfiguration -;;; Local Variables: *** -;;; c-basic-offset:4 *** -;;; End: *** -*/ diff -r c21e7c12dd50 -r 674071846ee3 master/device.h --- a/master/device.h Thu Apr 20 13:19:36 2006 +0000 +++ b/master/device.h Thu Apr 20 13:31:31 2006 +0000 @@ -2,7 +2,7 @@ * * d e v i c e . h * - * Struktur für ein EtherCAT-Gerät. + * EtherCAT device structure. * * $Id$ * @@ -20,23 +20,21 @@ /*****************************************************************************/ /** - EtherCAT-Gerät. + EtherCAT device. - Ein EtherCAT-Gerät ist eine Netzwerkkarte, die vom - EtherCAT-Master dazu verwendet wird, um Frames zu senden - und zu empfangen. + An EtherCAT device is a network interface card, that is owned by an + EtherCAT master to send and receive EtherCAT frames with. */ struct ec_device { - ec_master_t *master; /**< EtherCAT-Master */ - struct net_device *dev; /**< Zeiger auf das reservierte net_device */ - uint8_t open; /**< Das net_device ist geoeffnet. */ - struct sk_buff *tx_skb; /**< Zeiger auf Transmit-Socketbuffer */ - ec_isr_t isr; /**< Adresse der ISR */ - struct module *module; /**< Zeiger auf das Modul, das das Gerät zur - Verfügung stellt. */ - uint8_t link_state; /**< Verbindungszustand */ + ec_master_t *master; /**< EtherCAT master */ + struct net_device *dev; /**< pointer to the assigned net_device */ + uint8_t open; /**< true, if the net_device has been opened */ + struct sk_buff *tx_skb; /**< transmit socket buffer */ + ec_isr_t isr; /**< pointer to the device's interrupt service routine */ + struct module *module; /**< pointer to the device's owning module */ + uint8_t link_state; /**< device link state */ }; /*****************************************************************************/ @@ -55,9 +53,3 @@ /*****************************************************************************/ #endif - -/* Emacs-Konfiguration -;;; Local Variables: *** -;;; c-basic-offset:4 *** -;;; End: *** -*/ diff -r c21e7c12dd50 -r 674071846ee3 master/domain.c --- a/master/domain.c Thu Apr 20 13:19:36 2006 +0000 +++ b/master/domain.c Thu Apr 20 13:31:31 2006 +0000 @@ -2,7 +2,7 @@ * * d o m a i n . c * - * Methoden für Gruppen von EtherCAT-Slaves. + * EtherCAT domain methods. * * $Id$ * @@ -40,12 +40,13 @@ /*****************************************************************************/ /** - Konstruktor einer EtherCAT-Domäne. -*/ - -int ec_domain_init(ec_domain_t *domain, /**< Domäne */ - ec_master_t *master, /**< Zugehöriger Master */ - unsigned int index /**< Domänen-Index */ + Domain constructor. + \return 0 in case of success, else < 0 +*/ + +int ec_domain_init(ec_domain_t *domain, /**< EtherCAT domain */ + ec_master_t *master, /**< owning master */ + unsigned int index /**< domain index */ ) { domain->master = master; @@ -57,7 +58,7 @@ INIT_LIST_HEAD(&domain->field_regs); INIT_LIST_HEAD(&domain->commands); - // Init kobject and add it to the hierarchy + // init kobject and add it to the hierarchy memset(&domain->kobj, 0x00, sizeof(struct kobject)); kobject_init(&domain->kobj); domain->kobj.ktype = &ktype_ec_domain; @@ -73,10 +74,10 @@ /*****************************************************************************/ /** - Destruktor einer EtherCAT-Domäne. -*/ - -void ec_domain_clear(struct kobject *kobj /**< Kobject der Domäne */) + Domain destructor. +*/ + +void ec_domain_clear(struct kobject *kobj /**< kobject of the domain */) { ec_command_t *command, *next; ec_domain_t *domain; @@ -98,16 +99,16 @@ /*****************************************************************************/ /** - Registriert ein Feld in einer Domäne. - - \return 0 bei Erfolg, < 0 bei Fehler -*/ - -int ec_domain_reg_field(ec_domain_t *domain, /**< Domäne */ - ec_slave_t *slave, /**< Slave */ - const ec_sync_t *sync, /**< Sync-Manager */ - uint32_t field_offset, /**< Datenfeld-Offset */ - void **data_ptr /**< Adresse des Prozessdatenzeigers */ + Registeres a data field in a domain. + \return 0 in case of success, else < 0 +*/ + +int ec_domain_reg_field(ec_domain_t *domain, /**< EtherCAT domain */ + ec_slave_t *slave, /**< slave */ + const ec_sync_t *sync, /**< sync manager */ + uint32_t field_offset, /**< data field offset */ + void **data_ptr /**< pointer to the process data + pointer */ ) { ec_field_reg_t *field_reg; @@ -136,10 +137,10 @@ /*****************************************************************************/ /** - Gibt die Liste der registrierten Datenfelder frei. -*/ - -void ec_domain_clear_field_regs(ec_domain_t *domain) + Clears the list of the registered data fields. +*/ + +void ec_domain_clear_field_regs(ec_domain_t *domain /**< EtherCAT domain */) { ec_field_reg_t *field_reg, *next; @@ -152,12 +153,13 @@ /*****************************************************************************/ /** - Alloziert ein Prozessdatenkommando und fügt es in die Liste ein. -*/ - -int ec_domain_add_command(ec_domain_t *domain, /**< Domäne */ - uint32_t offset, /**< Logisches Offset */ - size_t data_size /**< Größe der Kommando-Daten */ + Allocates a process data command and appends it to the list. + \return 0 in case of success, else < 0 +*/ + +int ec_domain_add_command(ec_domain_t *domain, /**< EtherCAT domain */ + uint32_t offset, /**< logical offset */ + size_t data_size /**< size of the command data */ ) { ec_command_t *command; @@ -181,15 +183,14 @@ /*****************************************************************************/ /** - Erzeugt eine Domäne. - - Reserviert den Speicher einer Domäne, berechnet die logischen Adressen der - FMMUs und setzt die Prozessdatenzeiger der registrierten Felder. - - \return 0 bei Erfolg, < 0 bei Fehler -*/ - -int ec_domain_alloc(ec_domain_t *domain, /**< Domäne */ + Creates a domain. + Reserves domain memory, calculates the logical addresses of the + corresponding FMMUs and sets the process data pointer of the registered + data fields. + \return 0 in case of success, else < 0 +*/ + +int ec_domain_alloc(ec_domain_t *domain, /**< EtherCAT domain */ uint32_t base_address /**< Logische Basisadresse */ ) { @@ -276,30 +277,33 @@ /*****************************************************************************/ /** - Gibt die Anzahl der antwortenden Slaves aus. -*/ - -void ec_domain_response_count(ec_domain_t *domain, /**< Domäne */ - unsigned int count /**< Neue Anzahl */ + Sets the number of responding slaves and outputs it on demand. + This number isn't really the number of responding slaves, but the sum of + the working counters of all domain commands. Some slaves increase the + working counter by 2, some by 1. +*/ + +void ec_domain_response_count(ec_domain_t *domain, /**< EtherCAT domain */ + unsigned int count /**< new WC sum */ ) { if (count != domain->response_count) { domain->response_count = count; - EC_INFO("Domain %i working counter change: %i\n", domain->index, count); - } -} - -/*****************************************************************************/ - -/** - Formatiert Attribut-Daten für lesenden Zugriff im SysFS - - \return Anzahl Bytes im Speicher -*/ - -ssize_t ec_show_domain_attribute(struct kobject *kobj, /**< KObject */ - struct attribute *attr, /**< Attribut */ - char *buffer /**< Speicher für die Daten */ + EC_INFO("Domain %i working counter change: %i\n", domain->index, + count); + } +} + +/*****************************************************************************/ + +/** + Formats attribute data for SysFS reading. + \return number of bytes to read +*/ + +ssize_t ec_show_domain_attribute(struct kobject *kobj, /**< kobject */ + struct attribute *attr, /**< attribute */ + char *buffer /**< memory to store data in */ ) { ec_domain_t *domain = container_of(kobj, ec_domain_t, kobj); @@ -312,43 +316,39 @@ } /****************************************************************************** - * - * Echtzeitschnittstelle - * + * Realtime interface *****************************************************************************/ /** - Registriert ein Datenfeld innerhalb einer Domäne. - - - Ist \a data_ptr NULL, so wird der Slave nur auf den Typ überprüft. - - Wenn \a field_count 0 ist, wird angenommen, dass 1 Feld registriert werden - soll. - - Wenn \a field_count größer als 1 ist, wird angenommen, dass \a data_ptr - auf ein entsprechend großes Array zeigt. - - \return Zeiger auf den Slave bei Erfolg, sonst NULL + Registers a data field in a domain. + - If \a data_ptr is NULL, the slave is only checked against its type. + - If \a field_count is 0, it is assumed that one data field is to be + registered. + - If \a field_count is greater then 1, it is assumed that \a data_ptr + is an array of the respective size. + \return pointer to the slave on success, else NULL */ ec_slave_t *ecrt_domain_register_field(ec_domain_t *domain, - /**< Domäne */ + /**< EtherCAT domain */ const char *address, - /**< ASCII-Addresse des Slaves, - siehe ecrt_master_get_slave() */ + /**< ASCII address of the slave, + see ecrt_master_get_slave() */ const char *vendor_name, - /**< Herstellername */ + /**< vendor name */ const char *product_name, - /**< Produktname */ + /**< product name */ void **data_ptr, - /**< Adresse des Zeigers auf die - Prozessdaten */ + /**< address of the process data + pointer */ const char *field_name, - /**< Name des Datenfeldes */ + /**< data field name */ unsigned int field_index, - /**< Gibt an, ab welchem Feld mit - Typ \a field_type gezählt - werden soll. */ + /**< offset of data fields with + \a field_type */ unsigned int field_count - /**< Anzahl Felder selben Typs */ + /**< number of data fields (with + the same type) to register */ ) { ec_slave_t *slave; @@ -361,7 +361,7 @@ master = domain->master; - // Adresse übersetzen + // translate address if (!(slave = ecrt_master_get_slave(master, address))) return NULL; if (!(type = slave->type)) { @@ -379,7 +379,7 @@ } if (!data_ptr) { - // Wenn data_ptr NULL, Slave als registriert ansehen (nicht warnen). + // data_ptr is NULL => mark slave as "registered" (do not warn) slave->registered = 1; } @@ -415,17 +415,15 @@ /*****************************************************************************/ /** - Registriert eine ganze Liste von Datenfeldern innerhalb einer Domäne. - - Achtung: Die Liste muss mit einer NULL-Struktur ({}) abgeschlossen sein! - - \return 0 bei Erfolg, sonst < 0 + Registeres a bunch of data fields. + Caution! The list has to be terminated with a NULL structure ({})! + \return 0 in case of success, else < 0 */ int ecrt_domain_register_field_list(ec_domain_t *domain, - /**< Domäne */ + /**< EtherCAT domain */ const ec_field_init_t *fields - /**< Array mit Datenfeldern */ + /**< array of data field registrations */ ) { const ec_field_init_t *field; @@ -444,10 +442,10 @@ /*****************************************************************************/ /** - Setzt Prozessdaten-Kommandos in die Warteschlange des Masters. -*/ - -void ecrt_domain_queue(ec_domain_t *domain /**< Domäne */) + Places all process data commands in the masters command queue. +*/ + +void ecrt_domain_queue(ec_domain_t *domain /**< EtherCAT domain */) { ec_command_t *command; @@ -459,10 +457,10 @@ /*****************************************************************************/ /** - Verarbeitet empfangene Prozessdaten. -*/ - -void ecrt_domain_process(ec_domain_t *domain /**< Domäne */) + Processes received process data. +*/ + +void ecrt_domain_process(ec_domain_t *domain /**< EtherCAT domain */) { unsigned int working_counter_sum; ec_command_t *command; @@ -481,12 +479,11 @@ /*****************************************************************************/ /** - Gibt den Status einer Domäne zurück. - - \return 0 wenn alle Kommandos empfangen wurden, sonst -1. -*/ - -int ecrt_domain_state(ec_domain_t *domain /**< Domäne */) + Returns the state of a domain. + \return 0 if all commands were received, else -1. +*/ + +int ecrt_domain_state(ec_domain_t *domain /**< EtherCAT domain */) { ec_command_t *command; @@ -506,9 +503,3 @@ EXPORT_SYMBOL(ecrt_domain_state); /*****************************************************************************/ - -/* Emacs-Konfiguration -;;; Local Variables: *** -;;; c-basic-offset:4 *** -;;; End: *** -*/ diff -r c21e7c12dd50 -r 674071846ee3 master/domain.h --- a/master/domain.h Thu Apr 20 13:19:36 2006 +0000 +++ b/master/domain.h Thu Apr 20 13:31:31 2006 +0000 @@ -2,7 +2,7 @@ * * d o m a i n . h * - * Struktur für eine Gruppe von EtherCAT-Slaves. + * EtherCAT domain structure. * * $Id$ * @@ -21,39 +21,38 @@ /*****************************************************************************/ /** - Datenfeld-Konfiguration. + Data field registration type. */ typedef struct { - struct list_head list; - ec_slave_t *slave; - const ec_sync_t *sync; - uint32_t field_offset; - void **data_ptr; + struct list_head list; /**< list item */ + ec_slave_t *slave; /**< slave */ + const ec_sync_t *sync; /**< sync manager */ + uint32_t field_offset; /**< data field offset */ + void **data_ptr; /**< pointer to process data pointer(s) */ } ec_field_reg_t; /*****************************************************************************/ /** - EtherCAT-Domäne - - Verwaltet die Prozessdaten und das hierfür nötige Kommando einer bestimmten - Menge von Slaves. + EtherCAT domain. + Handles the process data and the therefore needed commands of a certain + group of slaves. */ struct ec_domain { - struct kobject kobj; /**< Kobject der Domäne */ - struct list_head list; /**< Listenkopf */ - unsigned int index; /**< Domänen-Index */ - ec_master_t *master; /**< EtherCAT-Master, zu der die Domäne gehört. */ - size_t data_size; /**< Größe der Prozessdaten */ - struct list_head commands; /**< EtherCAT-Kommandos für die Prozessdaten */ - uint32_t base_address; /**< Logische Basisaddresse der Domain */ - unsigned int response_count; /**< Anzahl antwortender Slaves */ - struct list_head field_regs; /**< Liste der Datenfeldregistrierungen */ + struct kobject kobj; /**< kobject */ + struct list_head list; /**< list item */ + unsigned int index; /**< domain index (just a number) */ + ec_master_t *master; /**< EtherCAT master owning the domain */ + size_t data_size; /**< size of the process data */ + struct list_head commands; /**< process data commands */ + uint32_t base_address; /**< logical offset address of the process data */ + unsigned int response_count; /**< number of responding slaves */ + struct list_head field_regs; /**< data field registrations */ }; /*****************************************************************************/ @@ -65,9 +64,3 @@ /*****************************************************************************/ #endif - -/* Emacs-Konfiguration -;;; Local Variables: *** -;;; c-basic-offset:4 *** -;;; End: *** -*/ diff -r c21e7c12dd50 -r 674071846ee3 master/ethernet.c --- a/master/ethernet.c Thu Apr 20 13:19:36 2006 +0000 +++ b/master/ethernet.c Thu Apr 20 13:31:31 2006 +0000 @@ -117,9 +117,3 @@ } /*****************************************************************************/ - -/* Emacs-Konfiguration -;;; Local Variables: *** -;;; c-basic-offset:4 *** -;;; End: *** -*/ diff -r c21e7c12dd50 -r 674071846ee3 master/ethernet.h --- a/master/ethernet.h Thu Apr 20 13:19:36 2006 +0000 +++ b/master/ethernet.h Thu Apr 20 13:31:31 2006 +0000 @@ -43,9 +43,3 @@ void ec_eoe_print(const ec_eoe_t *); /*****************************************************************************/ - -/* Emacs-Konfiguration -;;; Local Variables: *** -;;; c-basic-offset:4 *** -;;; End: *** -*/ diff -r c21e7c12dd50 -r 674071846ee3 master/globals.h --- a/master/globals.h Thu Apr 20 13:19:36 2006 +0000 +++ b/master/globals.h Thu Apr 20 13:31:31 2006 +0000 @@ -2,7 +2,7 @@ * * g l o b a l s . h * - * Globale Definitionen und Makros für das EtherCAT-Protokoll. + * Global definitions and macros. * * $Id$ * @@ -16,21 +16,20 @@ /*****************************************************************************/ // EtherCAT-Protokoll -#define EC_MAX_FRAME_SIZE 1500 /**< Maximale Größe eines EtherCAT-Frames ohne - Ethernet-II-Header und -Prüfsumme */ -#define EC_MIN_FRAME_SIZE 46 /** Minimale Größe, s. o. */ -#define EC_FRAME_HEADER_SIZE 2 /**< Größe des EtherCAT-Frame-Headers */ -#define EC_COMMAND_HEADER_SIZE 10 /**< Größe eines EtherCAT-Kommando-Headers */ -#define EC_COMMAND_FOOTER_SIZE 2 /**< Größe eines EtherCAT-Kommando-Footers */ -#define EC_SYNC_SIZE 8 /**< Größe einer Sync-Manager-Konfigurationsseite */ -#define EC_FMMU_SIZE 16 /**< Größe einer FMMU-Konfigurationsseite */ -#define EC_MAX_FMMUS 16 /**< Maximale Anzahl FMMUs pro Slave */ +#define EC_MAX_FRAME_SIZE 1500 /**< maximum size of an EtherCAT frame (without + header and CRC) */ +#define EC_MIN_FRAME_SIZE 46 /** ... minimum size */ +#define EC_FRAME_HEADER_SIZE 2 /**< size of an EtherCAT frame header */ +#define EC_COMMAND_HEADER_SIZE 10 /**< size of an EtherCAT command header */ +#define EC_COMMAND_FOOTER_SIZE 2 /**< size of an EtherCAT command footer */ +#define EC_SYNC_SIZE 8 /**< size of a sync manager configuration page */ +#define EC_FMMU_SIZE 16 /**< size of an FMMU configuration page */ +#define EC_MAX_FMMUS 16 /**< maximum number of FMMUs per slave */ #define EC_MAX_DATA_SIZE (EC_MAX_FRAME_SIZE \ - EC_FRAME_HEADER_SIZE \ - EC_COMMAND_HEADER_SIZE \ - - EC_COMMAND_FOOTER_SIZE) /**< Maximale Datengröße - bei einem Kommando pro - Frame */ + - EC_COMMAND_FOOTER_SIZE) /**< maximum data size of a + single command */ /*****************************************************************************/ @@ -59,16 +58,15 @@ /*****************************************************************************/ /** - Code - Message Pair. - + Code - Message pair. Some EtherCAT commands support reading a status code to display a certain message. This type allows to map a code to a message string. */ typedef struct { - uint32_t code; /**< Code */ - const char *message; /**< Message belonging to \a code */ + uint32_t code; /**< code */ + const char *message; /**< message belonging to \a code */ } ec_code_msg_t; @@ -76,8 +74,3 @@ #endif -/* Emacs-Konfiguration -;;; Local Variables: *** -;;; c-basic-offset:4 *** -;;; End: *** -*/ diff -r c21e7c12dd50 -r 674071846ee3 master/mailbox.c --- a/master/mailbox.c Thu Apr 20 13:19:36 2006 +0000 +++ b/master/mailbox.c Thu Apr 20 13:31:31 2006 +0000 @@ -2,7 +2,7 @@ * * m a i l b o x . c * - * Mailbox-Funktionen + * Mailbox functionality. * * $Id$ * @@ -18,12 +18,13 @@ /*****************************************************************************/ /** - Bereitet ein Mailbox-Send-Kommando vor. - */ - -uint8_t *ec_slave_mbox_prepare_send(ec_slave_t *slave, /**< Slave */ - uint8_t type, /**< Mailbox-Protokoll */ - size_t size /**< Datengröße */ + Prepares a mailbox-send command. + \return pointer to mailbox command data +*/ + +uint8_t *ec_slave_mbox_prepare_send(ec_slave_t *slave, /**< slave */ + uint8_t type, /**< mailbox protocol */ + size_t size /**< size of the data */ ) { ec_command_t *command = &slave->mbox_command; @@ -46,10 +47,10 @@ slave->sii_rx_mailbox_size)) return NULL; - EC_WRITE_U16(command->data, size); // Mailbox service data length - EC_WRITE_U16(command->data + 2, slave->station_address); // Station address - EC_WRITE_U8 (command->data + 4, 0x00); // Channel & priority - EC_WRITE_U8 (command->data + 5, type); // Underlying protocol type + EC_WRITE_U16(command->data, size); // mailbox service data length + EC_WRITE_U16(command->data + 2, slave->station_address); // station address + EC_WRITE_U8 (command->data + 4, 0x00); // hhannel & priority + EC_WRITE_U8 (command->data + 5, type); // underlying protocol type return command->data + 6; } @@ -57,14 +58,15 @@ /*****************************************************************************/ /** - Bereitet ein Kommando zum Abfragen des Mailbox-Zustandes vor. - */ - -int ec_slave_mbox_prepare_check(ec_slave_t *slave /**< Slave */) -{ - ec_command_t *command = &slave->mbox_command; - - // FIXME: Zweiter Sync-Manager nicht immer TX-Mailbox? + Prepares a command for checking the mailbox state. + \return 0 in case of success, else < 0 +*/ + +int ec_slave_mbox_prepare_check(ec_slave_t *slave /**< slave */) +{ + ec_command_t *command = &slave->mbox_command; + + // FIXME: second sync manager? if (ec_command_nprd(command, slave->station_address, 0x808, 8)) return -1; @@ -74,10 +76,11 @@ /*****************************************************************************/ /** - Liest den Mailbox-Zustand aus einem empfangenen Kommando. - */ - -int ec_slave_mbox_check(const ec_slave_t *slave /**< Slave */) + Processes a mailbox state checking command. + \return 0 in case of success, else < 0 +*/ + +int ec_slave_mbox_check(const ec_slave_t *slave /**< slave */) { return EC_READ_U8(slave->mbox_command.data + 5) & 8 ? 1 : 0; } @@ -85,10 +88,11 @@ /*****************************************************************************/ /** - Bereitet ein Kommando zum Laden von Daten von der Mailbox vor. - */ - -int ec_slave_mbox_prepare_fetch(ec_slave_t *slave /**< Slave */) + Prepares a command to fetch mailbox data. + \return 0 in case of success, else < 0 +*/ + +int ec_slave_mbox_prepare_fetch(ec_slave_t *slave /**< slave */) { ec_command_t *command = &slave->mbox_command; @@ -101,12 +105,13 @@ /*****************************************************************************/ /** - Verarbeitet empfangene Mailbox-Daten. - */ - -uint8_t *ec_slave_mbox_fetch(ec_slave_t *slave, /**< Slave */ - uint8_t type, /**< Protokoll */ - size_t *size /**< Größe der empfangenen Daten */ + Processes received mailbox data. + \return pointer to the received data +*/ + +uint8_t *ec_slave_mbox_fetch(ec_slave_t *slave, /**< slave */ + uint8_t type, /**< expected mailbox protocol */ + size_t *size /**< size of the received data */ ) { ec_command_t *command = &slave->mbox_command; @@ -132,12 +137,12 @@ /*****************************************************************************/ /** - Sendet und wartet auf den Empfang eines Mailbox-Kommandos. - */ - -uint8_t *ec_slave_mbox_simple_io(ec_slave_t *slave, /**< Slave */ - size_t *size /**< Größe der gelesenen - Daten */ + Sends a mailbox command and waits for its reception. + \return pointer to the received data +*/ + +uint8_t *ec_slave_mbox_simple_io(ec_slave_t *slave, /**< slave */ + size_t *size /**< size of the received data */ ) { uint8_t type; @@ -158,13 +163,13 @@ /*****************************************************************************/ /** - Wartet auf den Empfang eines Mailbox-Kommandos. - */ - -uint8_t *ec_slave_mbox_simple_receive(ec_slave_t *slave, /**< Slave */ - uint8_t type, /**< Protokoll */ - size_t *size /**< Größe der gelesenen - Daten */ + Waits for the reception of a mailbox command. + \return pointer to the received data +*/ + +uint8_t *ec_slave_mbox_simple_receive(ec_slave_t *slave, /**< slave */ + uint8_t type, /**< expected protocol */ + size_t *size /**< received data size */ ) { cycles_t start, end, timeout; @@ -186,7 +191,7 @@ end = get_cycles(); if (ec_slave_mbox_check(slave)) - break; // Proceed with receiving data + break; // proceed with receiving data if ((end - start) >= timeout) { EC_ERR("Mailbox check - Slave %i timed out.\n", diff -r c21e7c12dd50 -r 674071846ee3 master/mailbox.h --- a/master/mailbox.h Thu Apr 20 13:19:36 2006 +0000 +++ b/master/mailbox.h Thu Apr 20 13:31:31 2006 +0000 @@ -2,7 +2,7 @@ * * m a i l b o x . h * - * Mailbox-Funktionen. + * Mailbox functionality. * * $Id$ * @@ -27,9 +27,3 @@ /*****************************************************************************/ #endif - -/* Emacs-Konfiguration -;;; Local Variables: *** -;;; c-basic-offset:4 *** -;;; End: *** -*/ diff -r c21e7c12dd50 -r 674071846ee3 master/master.c --- a/master/master.c Thu Apr 20 13:19:36 2006 +0000 +++ b/master/master.c Thu Apr 20 13:31:31 2006 +0000 @@ -2,7 +2,7 @@ * * m a s t e r . c * - * Methoden für einen EtherCAT-Master. + * EtherCAT master methods. * * $Id$ * @@ -27,6 +27,7 @@ void ec_master_freerun(unsigned long); ssize_t ec_show_master_attribute(struct kobject *, struct attribute *, char *); +void ec_master_process_watch_command(ec_master_t *); /*****************************************************************************/ @@ -53,11 +54,12 @@ /*****************************************************************************/ /** - Konstruktor des EtherCAT-Masters. -*/ - -int ec_master_init(ec_master_t *master, /**< EtherCAT-Master */ - unsigned int index /**< Master-Index */ + Master constructor. + \return 0 in case of success, else < 0 +*/ + +int ec_master_init(ec_master_t *master, /**< EtherCAT master */ + unsigned int index /**< master index */ ) { EC_INFO("Initializing master %i.\n", index); @@ -71,7 +73,7 @@ INIT_LIST_HEAD(&master->domains); INIT_LIST_HEAD(&master->eoe_slaves); - // Init kobject and add it to the hierarchy + // init kobject and add it to the hierarchy memset(&master->kobj, 0x00, sizeof(struct kobject)); kobject_init(&master->kobj); master->kobj.ktype = &ktype_ec_master; @@ -81,7 +83,7 @@ return -1; } - // Init freerun timer + // init freerun timer init_timer(&master->freerun_timer); master->freerun_timer.function = ec_master_freerun; master->freerun_timer.data = (unsigned long) master; @@ -96,13 +98,12 @@ /*****************************************************************************/ /** - Destruktor eines EtherCAT-Masters. - - Entfernt alle Kommandos aus der Liste, löscht den Zeiger - auf das Slave-Array und gibt die Prozessdaten frei. -*/ - -void ec_master_clear(struct kobject *kobj /**< KObject des Masters */) + Master destructor. + Removes all pending commands, clears the slave list, clears all domains + and frees the device. +*/ + +void ec_master_clear(struct kobject *kobj /**< kobject of the master */) { ec_master_t *master = container_of(kobj, ec_master_t, kobj); @@ -126,15 +127,12 @@ /*****************************************************************************/ /** - Setzt den Master zurück in den Ausgangszustand. - - Bei einem "release" sollte immer diese Funktion aufgerufen werden, - da sonst Slave-Liste, Domains, etc. weiter existieren. -*/ - -void ec_master_reset(ec_master_t *master - /**< Zeiger auf den zurückzusetzenden Master */ - ) + Resets the master. + Note: This function has to be called, everytime ec_master_release() is + called, to free the slave list, domains etc. +*/ + +void ec_master_reset(ec_master_t *master /**< EtherCAT master */) { ec_slave_t *slave, *next_s; ec_command_t *command, *next_c; @@ -143,7 +141,7 @@ ec_master_freerun_stop(master); - // Alle Slaves entfernen + // remove all slaves list_for_each_entry_safe(slave, next_s, &master->slaves, list) { list_del(&slave->list); kobject_del(&slave->kobj); @@ -151,20 +149,20 @@ } master->slave_count = 0; - // Kommando-Warteschlange leeren + // empty command queue list_for_each_entry_safe(command, next_c, &master->command_queue, queue) { list_del_init(&command->queue); command->state = EC_CMD_ERROR; } - // Domain-Liste leeren + // clear domains list_for_each_entry_safe(domain, next_d, &master->domains, list) { list_del(&domain->list); kobject_del(&domain->kobj); kobject_put(&domain->kobj); } - // EOE-Liste leeren + // clear EoE objects list_for_each_entry_safe(eoe, next_eoe, &master->eoe_slaves, list) { list_del(&eoe->list); ec_eoe_clear(eoe); @@ -191,16 +189,16 @@ /*****************************************************************************/ /** - Stellt ein Kommando in die Warteschlange. -*/ - -void ec_master_queue_command(ec_master_t *master, /**< EtherCAT-Master */ - ec_command_t *command /**< Kommando */ + Places a command in the command queue. +*/ + +void ec_master_queue_command(ec_master_t *master, /**< EtherCAT master */ + ec_command_t *command /**< command */ ) { ec_command_t *queued_command; - // Ist das Kommando schon in der Warteschlange? + // check, if the command is already queued list_for_each_entry(queued_command, &master->command_queue, queue) { if (queued_command == command) { command->state = EC_CMD_QUEUED; @@ -217,12 +215,11 @@ /*****************************************************************************/ /** - Sendet die Kommandos in der Warteschlange. - - \return 0 bei Erfolg, sonst < 0 -*/ - -void ec_master_send_commands(ec_master_t *master /**< EtherCAT-Master */) + Sends the commands in the queue. + \return 0 in case of success, else < 0 +*/ + +void ec_master_send_commands(ec_master_t *master /**< EtherCAT master */) { ec_command_t *command; size_t command_size; @@ -239,17 +236,17 @@ } do { - // Zeiger auf Socket-Buffer holen + // fetch pointer to transmit socket buffer frame_data = ec_device_tx_data(master->device); cur_data = frame_data + EC_FRAME_HEADER_SIZE; follows_word = NULL; more_commands_waiting = 0; - // Aktuellen Frame mit Kommandos füllen + // fill current frame with commands list_for_each_entry(command, &master->command_queue, queue) { if (command->state != EC_CMD_QUEUED) continue; - // Passt das aktuelle Kommando noch in den aktuellen Rahmen? + // does the current command fit in the frame? command_size = EC_COMMAND_HEADER_SIZE + command->data_size + EC_COMMAND_FOOTER_SIZE; if (cur_data - frame_data + command_size > EC_MAX_FRAME_SIZE) { @@ -263,7 +260,7 @@ if (unlikely(master->debug_level > 0)) EC_DBG("adding command 0x%02X\n", command->index); - // Command-Following-Flag im letzten Kommando setzen + // set "command following" flag in previous frame if (follows_word) EC_WRITE_U16(follows_word, EC_READ_U16(follows_word) | 0x8000); @@ -281,7 +278,7 @@ cur_data += command->data_size; // EtherCAT command footer - EC_WRITE_U16(cur_data, 0x0000); // Working counter + EC_WRITE_U16(cur_data, 0x0000); // reset working counter cur_data += EC_COMMAND_FOOTER_SIZE; } @@ -295,14 +292,14 @@ EC_WRITE_U16(frame_data, ((cur_data - frame_data - EC_FRAME_HEADER_SIZE) & 0x7FF) | 0x1000); - // Rahmen auffüllen + // pad frame while (cur_data - frame_data < EC_MIN_FRAME_SIZE) EC_WRITE_U8(cur_data++, 0x00); if (unlikely(master->debug_level > 0)) EC_DBG("frame size: %i\n", cur_data - frame_data); - // Send frame + // send frame ec_device_send(master->device, cur_data - frame_data); frame_count++; } @@ -319,16 +316,14 @@ /** Processes a received frame. - This function is called by the network driver for every received frame. - - \return 0 bei Erfolg, sonst < 0 -*/ - -void ec_master_receive(ec_master_t *master, /**< EtherCAT-Master */ - const uint8_t *frame_data, /**< Empfangene Daten */ - size_t size /**< Anzahl empfangene Datenbytes */ - ) + \return 0 in case of success, else < 0 +*/ + +void ec_master_receive(ec_master_t *master, /**< EtherCAT master */ + const uint8_t *frame_data, /**< received data */ + size_t size /**< size of the received data */ + ) { size_t frame_size, data_size; uint8_t command_type, command_index; @@ -344,7 +339,7 @@ cur_data = frame_data; - // Länge des gesamten Frames prüfen + // check length of entire frame frame_size = EC_READ_U16(cur_data) & 0x07FF; cur_data += EC_FRAME_HEADER_SIZE; @@ -356,7 +351,7 @@ cmd_follows = 1; while (cmd_follows) { - // Kommando-Header auswerten + // process command header command_type = EC_READ_U8 (cur_data); command_index = EC_READ_U8 (cur_data + 1); data_size = EC_READ_U16(cur_data + 6) & 0x07FF; @@ -370,7 +365,7 @@ return; } - // Suche passendes Kommando in der Liste + // search for matching command in the queue matched = 0; list_for_each_entry(command, &master->command_queue, queue) { if (command->state == EC_CMD_SENT @@ -382,7 +377,7 @@ } } - // Kein passendes Kommando in der Liste gefunden + // no matching command was found if (!matched) { master->stats.unmatched++; ec_master_output_stats(master); @@ -390,15 +385,15 @@ continue; } - // Empfangene Daten in Kommando-Datenspeicher kopieren + // copy received data in the command memory memcpy(command->data, cur_data, data_size); cur_data += data_size; - // Working-Counter setzen + // set the command's working counter command->working_counter = EC_READ_U16(cur_data); cur_data += EC_COMMAND_FOOTER_SIZE; - // Kommando aus der Warteschlange entfernen + // dequeue the received command command->state = EC_CMD_RECEIVED; list_del_init(&command->queue); } @@ -407,16 +402,13 @@ /*****************************************************************************/ /** - Sendet ein einzelnes Kommando und wartet auf den Empfang. - - Wenn der Slave nicht antwortet, wird das Kommando - nochmals gesendet. - - \return 0 bei Erfolg, sonst < 0 -*/ - -int ec_master_simple_io(ec_master_t *master, /**< EtherCAT-Master */ - ec_command_t *command /**< Kommando */ + Sends a single command and waits for its reception. + If the slave doesn't respond, the command is sent again. + \return 0 in case of success, else < 0 +*/ + +int ec_master_simple_io(ec_master_t *master, /**< EtherCAT master */ + ec_command_t *command /**< command */ ) { unsigned int response_tries_left; @@ -441,7 +433,7 @@ return -1; } - // Keine direkte Antwort. Dem Slave Zeit lassen... + // no direct response, wait a little bit... udelay(100); if (unlikely(--response_tries_left)) { @@ -454,15 +446,12 @@ /*****************************************************************************/ /** - Durchsucht den EtherCAT-Bus nach Slaves. - - Erstellt ein Array mit allen Slave-Informationen die für den - weiteren Betrieb notwendig sind. - - \return 0 bei Erfolg, sonst < 0 -*/ - -int ec_master_bus_scan(ec_master_t *master /**< EtherCAT-Master */) + Scans the EtherCAT bus for slaves. + Creates a list of slave structures for further processing. + \return 0 in case of success, else < 0 +*/ + +int ec_master_bus_scan(ec_master_t *master /**< EtherCAT master */) { ec_slave_t *slave, *next; ec_slave_ident_t *ident; @@ -479,7 +468,7 @@ command = &master->simple_command; - // Determine number of slaves on bus + // determine number of slaves on bus if (ec_command_brd(command, 0x0000, 4)) return -1; if (unlikely(ec_master_simple_io(master, command))) return -1; master->slave_count = command->working_counter; @@ -487,7 +476,7 @@ if (!master->slave_count) return 0; - // Init slaves + // init slaves for (i = 0; i < master->slave_count; i++) { if (!(slave = (ec_slave_t *) kmalloc(sizeof(ec_slave_t), GFP_KERNEL))) { EC_ERR("Failed to allocate slave %i!\n", i); @@ -510,10 +499,10 @@ current_coupler_index = 0x3FFF; coupler_subindex = 0; - // For every slave on the bus + // for every slave on the bus list_for_each_entry(slave, &master->slaves, list) { - // Write station address + // write station address if (ec_command_apwr(command, slave->ring_position, 0x0010, sizeof(uint16_t))) goto out_free; EC_WRITE_U16(command->data, slave->station_address); @@ -523,10 +512,10 @@ goto out_free; } - // Fetch all slave information + // fetch all slave information if (ec_slave_fetch(slave)) goto out_free; - // Search for identification in "database" + // search for identification in "database" ident = slave_idents; while (ident->type) { if (unlikely(ident->vendor_id == slave->sii_vendor_id @@ -554,7 +543,7 @@ slave->coupler_subindex = coupler_subindex; coupler_subindex++; - // Does the slave support EoE? + // does the slave support EoE? if (slave->sii_mailbox_protocols & EC_MBOX_EOE) { if (!(eoe = (ec_eoe_t *) kmalloc(sizeof(ec_eoe_t), GFP_KERNEL))) { EC_ERR("Failed to allocate EoE-Object.\n"); @@ -580,15 +569,12 @@ /*****************************************************************************/ /** - Statistik-Ausgaben während des zyklischen Betriebs. - - Diese Funktion sorgt dafür, dass Statistiken während des zyklischen - Betriebs bei Bedarf, aber nicht zu oft ausgegeben werden. - - Die Ausgabe erfolgt gesammelt höchstens einmal pro Sekunde. -*/ - -void ec_master_output_stats(ec_master_t *master /**< EtherCAT-Master */) + Output statistics in cyclic mode. + This function outputs statistical data on demand, but not more often than + necessary. The output happens at most once a second. +*/ + +void ec_master_output_stats(ec_master_t *master /**< EtherCAT master */) { cycles_t t_now = get_cycles(); @@ -620,7 +606,7 @@ /*****************************************************************************/ /** - Starts Free-Run mode. + Starts the Free-Run mode. */ void ec_master_freerun_start(ec_master_t *master /**< EtherCAT master */) @@ -636,6 +622,15 @@ master->mode = EC_MASTER_MODE_FREERUN; + if (master->watch_command.state == EC_CMD_INIT) { + if (ec_command_brd(&master->watch_command, 0x130, 2)) { + EC_ERR("Failed to allocate watchdog command!\n"); + return; + } + } + + ecrt_master_prepare_async_io(master); + master->freerun_timer.expires = jiffies + 10; add_timer(&master->freerun_timer); } @@ -643,7 +638,7 @@ /*****************************************************************************/ /** - Stops Free-Run mode. + Stops the Free-Run mode. */ void ec_master_freerun_stop(ec_master_t *master /**< EtherCAT master */) @@ -662,11 +657,19 @@ Free-Run mode function. */ -void ec_master_freerun(unsigned long data) +void ec_master_freerun(unsigned long data /**< private timer data = master */) { ec_master_t *master = (ec_master_t *) data; - // nop + ecrt_master_async_receive(master); + + // watchdog command + ec_master_process_watch_command(master); + ec_master_queue_command(master, &master->watch_command); + + master->slave_count = master->watch_command.working_counter; + + ecrt_master_async_send(master); master->freerun_timer.expires += HZ; add_timer(&master->freerun_timer); @@ -675,22 +678,19 @@ /*****************************************************************************/ /** - Wandelt eine ASCII-kodierte Bus-Adresse in einen Slave-Zeiger. - - Gültige Adress-Strings sind Folgende: - - \a "X" = der X. Slave im Bus, - - \a "X:Y" = der Y. Slave hinter dem X. Buskoppler, - - \a "#X" = der Slave mit dem Alias X, - - \a "#X:Y" = der Y. Slave hinter dem Buskoppler mit dem Alias X. - - X und Y fangen immer bei 0 an und können auch hexadezimal oder oktal - angegeben werden (mit entsprechendem Prefix). - - \return Zeiger auf Slave bei Erfolg, sonst NULL + Translates an ASCII coded bus-address to a slave pointer. + These are the valid addressing schemes: + - \a "X" = the X. slave on the bus, + - \a "X:Y" = the Y. slave after the X. branch (bus coupler), + - \a "#X" = the slave with alias X, + - \a "#X:Y" = the Y. slave after the branch (bus coupler) with alias X. + X and Y are zero-based indices and may be provided in hexadecimal or octal + notation (with respective prefix). + \return pointer to the slave on success, else NULL */ ec_slave_t *ecrt_master_get_slave(const ec_master_t *master, /**< Master */ - const char *address /**< Address-String */ + const char *address /**< address string */ ) { unsigned long first, second; @@ -785,14 +785,12 @@ /*****************************************************************************/ /** - Initialisiert eine Sync-Manager-Konfigurationsseite. - - Der mit \a data referenzierte Speicher muss mindestens EC_SYNC_SIZE Bytes - groß sein. -*/ - -void ec_sync_config(const ec_sync_t *sync, /**< Sync-Manager */ - uint8_t *data /**> Zeiger auf Konfigurationsspeicher */ + Initializes a sync manager configuration page. + The referenced memory (\a data) must be at least EC_SYNC_SIZE bytes. +*/ + +void ec_sync_config(const ec_sync_t *sync, /**< sync manager */ + uint8_t *data /**> configuration memory */ ) { EC_WRITE_U16(data, sync->physical_start_address); @@ -805,14 +803,12 @@ /*****************************************************************************/ /** - Initialisiert eine Sync-Manager-Konfigurationsseite mit EEPROM-Daten. - - Der mit \a data referenzierte Speicher muss mindestens EC_SYNC_SIZE Bytes - groß sein. -*/ - -void ec_eeprom_sync_config(const ec_eeprom_sync_t *sync, /**< Sync-Manager */ - uint8_t *data /**> Zeiger auf Konfig.-Speicher */ + Initializes a sync manager configuration page with EEPROM data. + The referenced memory (\a data) must be at least EC_SYNC_SIZE bytes. +*/ + +void ec_eeprom_sync_config(const ec_eeprom_sync_t *sync, /**< sync manager */ + uint8_t *data /**> configuration memory */ ) { EC_WRITE_U16(data, sync->physical_start_address); @@ -825,38 +821,35 @@ /*****************************************************************************/ /** - Initialisiert eine FMMU-Konfigurationsseite. - - Der mit \a data referenzierte Speicher muss mindestens EC_FMMU_SIZE Bytes - groß sein. -*/ - -void ec_fmmu_config(const ec_fmmu_t *fmmu, /**< Sync-Manager */ - uint8_t *data /**> Zeiger auf Konfigurationsspeicher */ + Initializes an FMMU configuration page. + The referenced memory (\a data) must be at least EC_FMMU_SIZE bytes. +*/ + +void ec_fmmu_config(const ec_fmmu_t *fmmu, /**< FMMU */ + uint8_t *data /**> configuration memory */ ) { EC_WRITE_U32(data, fmmu->logical_start_address); EC_WRITE_U16(data + 4, fmmu->sync->size); - EC_WRITE_U8 (data + 6, 0x00); // Logical start bit - EC_WRITE_U8 (data + 7, 0x07); // Logical end bit + EC_WRITE_U8 (data + 6, 0x00); // logical start bit + EC_WRITE_U8 (data + 7, 0x07); // logical end bit EC_WRITE_U16(data + 8, fmmu->sync->physical_start_address); - EC_WRITE_U8 (data + 10, 0x00); // Physical start bit + EC_WRITE_U8 (data + 10, 0x00); // physical start bit EC_WRITE_U8 (data + 11, (fmmu->sync->control_byte & 0x04) ? 0x02 : 0x01); - EC_WRITE_U16(data + 12, 0x0001); // Enable - EC_WRITE_U16(data + 14, 0x0000); // res. -} - -/*****************************************************************************/ - -/** - Formatiert Attribut-Daten für lesenden Zugriff im SysFS - - \return Anzahl Bytes im Speicher -*/ - -ssize_t ec_show_master_attribute(struct kobject *kobj, /**< KObject */ - struct attribute *attr, /**< Attribut */ - char *buffer /**< Speicher für die Daten */ + EC_WRITE_U16(data + 12, 0x0001); // enable + EC_WRITE_U16(data + 14, 0x0000); // reserved +} + +/*****************************************************************************/ + +/** + Formats attribute data for SysFS read access. + \return number of bytes to read +*/ + +ssize_t ec_show_master_attribute(struct kobject *kobj, /**< kobject */ + struct attribute *attr, /**< attribute */ + char *buffer /**< memory to store data */ ) { ec_master_t *master = container_of(kobj, ec_master_t, kobj); @@ -881,11 +874,11 @@ /*****************************************************************************/ /** - Gibt Überwachungsinformationen aus. + Processes the watchdog command. */ void ec_master_process_watch_command(ec_master_t *master - /**< EtherCAT-Master */ + /**< EtherCAT master */ ) { unsigned int first; @@ -926,18 +919,15 @@ } /****************************************************************************** - * - * Echtzeitschnittstelle - * + * Realtime interface *****************************************************************************/ /** - Erstellt eine neue Domäne. - - \return Zeiger auf die Domäne bei Erfolg, sonst NULL. -*/ - -ec_domain_t *ecrt_master_create_domain(ec_master_t *master /**< Master */) + Creates a domain. + \return pointer to new domain on success, else NULL +*/ + +ec_domain_t *ecrt_master_create_domain(ec_master_t *master /**< master */) { ec_domain_t *domain, *last_domain; unsigned int index; @@ -975,16 +965,14 @@ /*****************************************************************************/ /** - Konfiguriert alle Slaves und setzt den Operational-Zustand. - - Führt die komplette Konfiguration und Aktivierunge aller registrierten - Slaves durch. Setzt Sync-Manager und FMMUs, führt die entsprechenden - Zustandsübergänge durch, bis der Slave betriebsbereit ist. - - \return 0 bei Erfolg, sonst < 0 -*/ - -int ecrt_master_activate(ec_master_t *master /**< EtherCAT-Master */) + Configures all slaves and leads them to the OP state. + Does the complete configuration and activation for all slaves. Sets sync + managers and FMMUs, and does the appropriate transitions, until the slave + is operational. + \return 0 in case of success, else < 0 +*/ + +int ecrt_master_activate(ec_master_t *master /**< EtherCAT master */) { unsigned int j; ec_slave_t *slave; @@ -998,12 +986,14 @@ command = &master->simple_command; - if (ec_command_brd(&master->watch_command, 0x130, 2)) { - EC_ERR("Failed to allocate watchdog command!\n"); - return -1; - } - - // Domains erstellen + if (master->watch_command.state == EC_CMD_INIT) { + if (ec_command_brd(&master->watch_command, 0x130, 2)) { + EC_ERR("Failed to allocate watchdog command!\n"); + return -1; + } + } + + // allocate all domains domain_offset = 0; list_for_each_entry(domain, &master->domains, list) { if (ec_domain_alloc(domain, domain_offset)) { @@ -1013,22 +1003,22 @@ domain_offset += domain->data_size; } - // Slaves aktivieren + // configure and activate slaves list_for_each_entry(slave, &master->slaves, list) { - // Change state to INIT + // change state to INIT if (unlikely(ec_slave_state_change(slave, EC_SLAVE_STATE_INIT))) return -1; - // Check if slave was registered... + // check for slave registration type = slave->type; if (!type) EC_WARN("Slave %i has unknown type!\n", slave->ring_position); - // Check and reset CRC fault counters + // check and reset CRC fault counters ec_slave_check_crc(slave); - // Resetting FMMUs + // reset FMMUs if (slave->base_fmmu_count) { if (ec_command_npwr(command, slave->station_address, 0x0600, EC_FMMU_SIZE * slave->base_fmmu_count)) @@ -1041,7 +1031,7 @@ } } - // Resetting Sync Manager channels + // reset sync managers if (slave->base_sync_count) { if (ec_command_npwr(command, slave->station_address, 0x0800, EC_SYNC_SIZE * slave->base_sync_count)) @@ -1054,10 +1044,8 @@ } } - // Set Sync Managers - - // Known slave type, take type's SM information - if (type) { + // configure sync managers + if (type) { // known slave type, take type's SM information for (j = 0; type->sync_managers[j] && j < EC_MAX_SYNC; j++) { sync = type->sync_managers[j]; if (ec_command_npwr(command, slave->station_address, @@ -1071,11 +1059,8 @@ } } } - - // Unknown slave type, but has mailbox - else if (slave->sii_mailbox_protocols) { - - // Does the device supply SM configurations in its EEPROM? + else if (slave->sii_mailbox_protocols) { // unknown type, but mailbox + // does the device supply SM configurations in its EEPROM? if (!list_empty(&slave->eeprom_syncs)) { list_for_each_entry(eeprom_sync, &slave->eeprom_syncs, list) { EC_INFO("Sync manager %i...\n", eeprom_sync->index); @@ -1091,9 +1076,7 @@ } } } - - // No sync manager information; guess mailbox settings - else { + else { // no sync manager information; guess mailbox settings mbox_sync.physical_start_address = slave->sii_rx_mailbox_offset; mbox_sync.length = slave->sii_rx_mailbox_size; @@ -1126,21 +1109,21 @@ slave->ring_position); } - // Change state to PREOP + // change state to PREOP if (unlikely(ec_slave_state_change(slave, EC_SLAVE_STATE_PREOP))) return -1; - // Stop activation here for slaves without type + // stop activation here for slaves without type if (!type) continue; - // Slaves that are not registered are only brought into PREOP + // slaves that are not registered are only brought into PREOP // state -> nice blinking and mailbox communication possible if (!slave->registered && !slave->type->special) { EC_WARN("Slave %i was not registered!\n", slave->ring_position); continue; } - // Set FMMUs + // configure FMMUs for (j = 0; j < slave->fmmu_count; j++) { fmmu = &slave->fmmus[j]; if (ec_command_npwr(command, slave->station_address, @@ -1154,11 +1137,11 @@ } } - // Change state to SAVEOP + // change state to SAVEOP if (unlikely(ec_slave_state_change(slave, EC_SLAVE_STATE_SAVEOP))) return -1; - // Change state to OP + // change state to OP if (unlikely(ec_slave_state_change(slave, EC_SLAVE_STATE_OP))) return -1; } @@ -1172,10 +1155,10 @@ /*****************************************************************************/ /** - Setzt alle Slaves zurück in den Init-Zustand. -*/ - -void ecrt_master_deactivate(ec_master_t *master /**< EtherCAT-Master */) + Resets all slaves to INIT state. +*/ + +void ecrt_master_deactivate(ec_master_t *master /**< EtherCAT master */) { ec_slave_t *slave; @@ -1189,14 +1172,12 @@ /*****************************************************************************/ /** - Lädt die SDO-Dictionaries aller Slaves. - - Slaves, die kein CoE unterstützen, werden ausgelassen. - - \return 0 wenn alles ok, sonst < 0 -*/ - -int ecrt_master_fetch_sdo_lists(ec_master_t *master /**< EtherCAT-Master */) + Fetches the SDO dictionaries of all slaves. + Slaves that do not support the CoE protocol are left out. + \return 0 in case of success, else < 0 +*/ + +int ecrt_master_fetch_sdo_lists(ec_master_t *master /**< EtherCAT master */) { ec_slave_t *slave; @@ -1216,27 +1197,26 @@ /*****************************************************************************/ /** - Sendet und empfängt Kommandos synchron. -*/ - -void ecrt_master_sync_io(ec_master_t *master) + Sends queued commands and waits for their reception. +*/ + +void ecrt_master_sync_io(ec_master_t *master /**< EtherCAT master */) { ec_command_t *command, *n; unsigned int commands_sent; cycles_t t_start, t_end, t_timeout; - // Kommandos senden + // send commands ecrt_master_async_send(master); - t_start = get_cycles(); // Sendezeit nehmen + t_start = get_cycles(); // measure io time t_timeout = (cycles_t) master->timeout * (cpu_khz / 1000); - while (1) // Aktiv auf Empfang warten - { + while (1) { // active waiting ec_device_call_isr(master->device); - t_end = get_cycles(); // Aktuelle Zeit nehmen - if (t_end - t_start >= t_timeout) break; // Timeout + t_end = get_cycles(); // take current time + if (t_end - t_start >= t_timeout) break; // timeout! commands_sent = 0; list_for_each_entry_safe(command, n, &master->command_queue, queue) { @@ -1249,7 +1229,7 @@ if (!commands_sent) break; } - // Zeit abgelaufen. Alle verbleibenden Kommandos entfernen. + // timeout; dequeue all commands list_for_each_entry_safe(command, n, &master->command_queue, queue) { switch (command->state) { case EC_CMD_SENT: @@ -1272,46 +1252,46 @@ /*****************************************************************************/ /** - Sendet Kommandos asynchron. -*/ - -void ecrt_master_async_send(ec_master_t *master) + Asynchronous sending of commands. +*/ + +void ecrt_master_async_send(ec_master_t *master /**< EtherCAT master */) { ec_command_t *command, *n; if (unlikely(!master->device->link_state)) { - // Link DOWN, keines der Kommandos kann gesendet werden. + // link is down, no command can be sent list_for_each_entry_safe(command, n, &master->command_queue, queue) { command->state = EC_CMD_ERROR; list_del_init(&command->queue); } - // Device-Zustand abfragen + // query link state ec_device_call_isr(master->device); return; } - // Rahmen senden + // send frames ec_master_send_commands(master); } /*****************************************************************************/ /** - Empfängt Kommandos asynchron. -*/ - -void ecrt_master_async_receive(ec_master_t *master) + Asynchronous receiving of commands. +*/ + +void ecrt_master_async_receive(ec_master_t *master /**< EtherCAT master */) { ec_command_t *command, *next; ec_device_call_isr(master->device); - // Alle empfangenen Kommandos aus der Liste entfernen + // dequeue all received commands list_for_each_entry_safe(command, next, &master->command_queue, queue) if (command->state == EC_CMD_RECEIVED) list_del_init(&command->queue); - // Alle verbleibenden Kommandos entfernen. + // dequeue all remaining commands list_for_each_entry_safe(command, next, &master->command_queue, queue) { switch (command->state) { case EC_CMD_SENT: @@ -1330,28 +1310,26 @@ /*****************************************************************************/ /** - Bereitet Synchronen Datenverkehr vor. - - Fürgt einmal die Kommandos aller Domains zur Warteschlange hinzu, sendet - diese ab und wartet so lange, bis diese anschließend problemlos empfangen - werden können. -*/ - -void ecrt_master_prepare_async_io(ec_master_t *master) + Prepares synchronous IO. + Queues all domain commands and sends them. Then waits a certain time, so + that ecrt_master_sasync_receive() can be called securely. +*/ + +void ecrt_master_prepare_async_io(ec_master_t *master /**< EtherCAT master */) { ec_domain_t *domain; cycles_t t_start, t_end, t_timeout; - // Kommandos aller Domains in die Warteschlange setzen + // queue commands of all domains list_for_each_entry(domain, &master->domains, list) ecrt_domain_queue(domain); ecrt_master_async_send(master); - t_start = get_cycles(); // Sendezeit nehmen + t_start = get_cycles(); // take sending time t_timeout = (cycles_t) master->timeout * (cpu_khz / 1000); - // Aktiv warten! + // active waiting while (1) { t_end = get_cycles(); if (t_end - t_start >= t_timeout) break; @@ -1361,15 +1339,15 @@ /*****************************************************************************/ /** - Führt Routinen im zyklischen Betrieb aus. -*/ - -void ecrt_master_run(ec_master_t *master /**< EtherCAT-Master */) -{ - // Statistiken ausgeben + Does all cyclic master work. +*/ + +void ecrt_master_run(ec_master_t *master /**< EtherCAT master */) +{ + // output statistics ec_master_output_stats(master); - // Watchdog-Kommando + // watchdog command ec_master_process_watch_command(master); ec_master_queue_command(master, &master->watch_command); @@ -1380,16 +1358,14 @@ /*****************************************************************************/ /** - Setzt die Debug-Ebene des Masters. - - Folgende Debug-Level sind definiert: - - - 1: Nur Positionsmarken in bestimmten Funktionen - - 2: Komplette Frame-Inhalte -*/ - -void ecrt_master_debug(ec_master_t *master, /**< EtherCAT-Master */ - int level /**< Debug-Level */ + Sets the debug level of the master. + The following levels are valid: + - 1: only output positions marks and basic data + - 2: additional frame data output +*/ + +void ecrt_master_debug(ec_master_t *master, /**< EtherCAT master */ + int level /**< debug level */ ) { if (level != master->debug_level) { @@ -1401,16 +1377,15 @@ /*****************************************************************************/ /** - Gibt alle Informationen zum Master aus. - + Outputs all master information. Verbosity: - 0 - Nur Slavetypen und Adressen - 1 - mit EEPROM-Informationen - >1 - mit SDO-Dictionaries -*/ - -void ecrt_master_print(const ec_master_t *master, /**< EtherCAT-Master */ - unsigned int verbosity /**< Geschwätzigkeit */ + - 0: Only slave types and positions + - 1: with EEPROM contents + - >1: with SDO dictionaries +*/ + +void ecrt_master_print(const ec_master_t *master, /**< EtherCAT master */ + unsigned int verbosity /**< verbosity level */ ) { ec_slave_t *slave; @@ -1433,7 +1408,11 @@ /*****************************************************************************/ -void ec_master_run_eoe(ec_master_t *master /**< EtherCAT-Master */) +/** + Does the Ethernet-over-EtherCAT processing. +*/ + +void ec_master_run_eoe(ec_master_t *master /**< EtherCAT master */) { ec_eoe_t *eoe; @@ -1458,9 +1437,3 @@ EXPORT_SYMBOL(ecrt_master_get_slave); /*****************************************************************************/ - -/* Emacs-Konfiguration -;;; Local Variables: *** -;;; c-basic-offset:4 *** -;;; End: *** -*/ diff -r c21e7c12dd50 -r 674071846ee3 master/master.h --- a/master/master.h Thu Apr 20 13:19:36 2006 +0000 +++ b/master/master.h Thu Apr 20 13:31:31 2006 +0000 @@ -2,7 +2,7 @@ * * m a s t e r . h * - * Struktur für einen EtherCAT-Master. + * EtherCAT master structure. * * $Id$ * @@ -35,61 +35,59 @@ /*****************************************************************************/ /** - EtherCAT-Rahmen-Statistiken. + Cyclic EtherCAT statistics. */ typedef struct { - unsigned int timeouts; /**< Kommando-Timeouts */ - unsigned int delayed; /**< Verzögerte Kommandos */ - unsigned int corrupted; /**< Verfälschte Rahmen */ - unsigned int unmatched; /**< Unpassende Kommandos */ - unsigned int eoe_errors; /**< Ethernet-over-EtherCAT Fehler */ - cycles_t t_last; /**< Timestamp-Counter bei der letzten Ausgabe */ + unsigned int timeouts; /**< command timeouts */ + unsigned int delayed; /**< delayed commands */ + unsigned int corrupted; /**< corrupted frames */ + unsigned int unmatched; /**< unmatched commands */ + unsigned int eoe_errors; /**< Ethernet-over-EtherCAT errors */ + cycles_t t_last; /**< time of last output */ } ec_stats_t; /*****************************************************************************/ /** - EtherCAT-Master - - Verwaltet die EtherCAT-Slaves und kommuniziert mit - dem zugewiesenen EtherCAT-Gerät. + EtherCAT-Master. + Manages slaves, domains and IO. */ struct ec_master { - struct list_head list; /**< Noetig fuer Master-Liste */ - struct kobject kobj; /**< Kernel-Object */ - unsigned int index; /**< Master-Index */ - struct list_head slaves; /**< Liste der Slaves auf dem Bus */ - unsigned int slave_count; /**< Anzahl Slaves auf dem Bus */ - ec_device_t *device; /**< EtherCAT-Gerät */ - struct list_head command_queue; /**< Kommando-Warteschlange */ - uint8_t command_index; /**< Aktueller Kommando-Index */ - struct list_head domains; /**< Liste der Prozessdatendomänen */ - ec_command_t simple_command; /**< Kommando für Initialisierungsphase */ - ec_command_t watch_command; /**< Kommando zum Überwachen der Slaves */ - unsigned int slaves_responding; /**< Anzahl antwortender Slaves */ - ec_slave_state_t slave_states; /**< Zustände der antwortenden Slaves */ - int debug_level; /**< Debug-Level im Master-Code */ - ec_stats_t stats; /**< Rahmen-Statistiken */ - unsigned int timeout; /**< Timeout für synchronen Datenaustausch */ - struct list_head eoe_slaves; /**< Ethernet over EtherCAT Slaves */ - unsigned int reserved; /**< Master durch Echtzeitprozess reserviert */ - struct timer_list freerun_timer; /**< Timer fuer Free-Run-Modus. */ - ec_master_mode_t mode; /**< Modus des Masters */ + struct list_head list; /**< list item */ + struct kobject kobj; /**< kobject */ + unsigned int index; /**< master index */ + struct list_head slaves; /**< list of slaves on the bus */ + unsigned int slave_count; /**< number of slaves on the bus */ + ec_device_t *device; /**< EtherCAT device */ + struct list_head command_queue; /**< command queue */ + uint8_t command_index; /**< current command index */ + struct list_head domains; /**< list of domains */ + ec_command_t simple_command; /**< command structure for initialization */ + ec_command_t watch_command; /**< command for watching the slaves */ + unsigned int slaves_responding; /**< number of responding slaves */ + ec_slave_state_t slave_states; /**< states of the responding slaves */ + int debug_level; /**< master debug level */ + ec_stats_t stats; /**< cyclic statistics */ + unsigned int timeout; /**< timeout in synchronous IO */ + struct list_head eoe_slaves; /**< Ethernet-over-EtherCAT slaves */ + unsigned int reserved; /**< true, if the master is reserved for RT */ + struct timer_list freerun_timer; /**< timer object for free run mode */ + ec_master_mode_t mode; /**< master mode */ }; /*****************************************************************************/ -// Master creation and deletion +// master creation and deletion int ec_master_init(ec_master_t *, unsigned int); void ec_master_clear(struct kobject *); void ec_master_reset(ec_master_t *); -// Free-Run +// free run void ec_master_freerun_start(ec_master_t *); void ec_master_freerun_stop(ec_master_t *); @@ -98,10 +96,10 @@ void ec_master_queue_command(ec_master_t *, ec_command_t *); int ec_master_simple_io(ec_master_t *, ec_command_t *); -// Slave management +// slave management int ec_master_bus_scan(ec_master_t *); -// Misc +// misc. void ec_master_debug(const ec_master_t *); void ec_master_output_stats(ec_master_t *); void ec_master_run_eoe(ec_master_t *); @@ -109,9 +107,3 @@ /*****************************************************************************/ #endif - -/* Emacs-Konfiguration -;;; Local Variables: *** -;;; c-basic-offset:4 *** -;;; End: *** -*/ diff -r c21e7c12dd50 -r 674071846ee3 master/module.c --- a/master/module.c Thu Apr 20 13:19:36 2006 +0000 +++ b/master/module.c Thu Apr 20 13:31:31 2006 +0000 @@ -2,9 +2,9 @@ * * m o d u l e . c * - * EtherCAT-Master-Treiber - * - * Autoren: Wilhelm Hagemeister, Florian Pose + * EtherCAT master driver module. + * + * Author: Florian Pose * * $Id$ * @@ -50,18 +50,14 @@ MODULE_VERSION(COMPILE_INFO); 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 ec_master_count - angegeben wurde (Default ist 1). - - \return 0 wenn alles ok, < 0 bei ungültiger Anzahl Master - oder zu wenig Speicher. +MODULE_PARM_DESC(ec_master_count, "number of EtherCAT masters to initialize"); + +/*****************************************************************************/ + +/** + Module initialization. + Initializes \a ec_master_count masters. + \return 0 on success, else < 0 */ int __init ec_init_module(void) @@ -115,9 +111,8 @@ /*****************************************************************************/ /** - Cleanup-Funktion des EtherCAT-Master-Treibermoduls - - Entfernt alle Master-Instanzen. + Module cleanup. + Clears all master instances. */ void __exit ec_cleanup_module(void) @@ -142,7 +137,7 @@ \returns pointer to master */ -ec_master_t *ec_find_master(unsigned int master_index) +ec_master_t *ec_find_master(unsigned int master_index /**< master index */) { ec_master_t *master; @@ -155,26 +150,19 @@ } /****************************************************************************** - * - * Treiberschnittstelle - * + * Device interface *****************************************************************************/ /** - Registeriert das EtherCAT-Geraet fuer einen EtherCAT-Master. - - \return 0 wenn alles ok, oder < 0 wenn bereits ein Gerät registriert - oder das Geraet nicht geöffnet werden konnte. -*/ - -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 */ + Registeres an EtherCAT device for a certain master. + \return 0 on success, else < 0 +*/ + +ec_device_t *ecdev_register(unsigned int master_index, /**< master index */ + struct net_device *net_dev, /**< net_device of + the device */ + ec_isr_t isr, /**< interrupt service routine */ + struct module *module /**< pointer to the module */ ) { ec_master_t *master; @@ -218,13 +206,11 @@ /*****************************************************************************/ /** - Hebt die Registrierung eines EtherCAT-Gerätes auf. -*/ - -void ecdev_unregister(unsigned int master_index, - /**< Index des EtherCAT-Masters */ - ec_device_t *device - /**< EtherCAT-Geraet */ + Unregisteres an EtherCAT device. +*/ + +void ecdev_unregister(unsigned int master_index, /**< master index */ + ec_device_t *device /**< EtherCAT device */ ) { ec_master_t *master; @@ -244,12 +230,10 @@ /*****************************************************************************/ /** - Starts the master. -*/ - -int ecdev_start(unsigned int master_index - /**< Index des EtherCAT-Masters */ - ) + Starts the master associated with the device. +*/ + +int ecdev_start(unsigned int master_index /**< master index */) { ec_master_t *master; if (!(master = ec_find_master(master_index))) return -1; @@ -266,12 +250,10 @@ /*****************************************************************************/ /** - Stops the master. -*/ - -void ecdev_stop(unsigned int master_index - /**< Index des EtherCAT-Masters */ - ) + Stops the master associated with the device. +*/ + +void ecdev_stop(unsigned int master_index /**< master index */) { ec_master_t *master; if (!(master = ec_find_master(master_index))) return; @@ -283,21 +265,16 @@ } /****************************************************************************** - * - * Echtzeitschnittstelle - * + * Realtime interface *****************************************************************************/ /** - Reserviert einen bestimmten EtherCAT-Master und das zugehörige Gerät. - - Gibt einen Zeiger auf den reservierten EtherCAT-Master zurueck. - - \return Zeiger auf EtherCAT-Master oder NULL, wenn Parameter ungueltig. + Reserves an EtherCAT master for realtime operation. + \return pointer to reserved master, or NULL on error */ ec_master_t *ecrt_request_master(unsigned int master_index - /**< EtherCAT-Master-Index */ + /**< master index */ ) { ec_master_t *master; @@ -351,10 +328,10 @@ /*****************************************************************************/ /** - Gibt einen zuvor angeforderten EtherCAT-Master wieder frei. -*/ - -void ecrt_release_master(ec_master_t *master /**< EtherCAT-Master */) + Releases a reserved EtherCAT master. +*/ + +void ecrt_release_master(ec_master_t *master /**< EtherCAT master */) { EC_INFO("Releasing master %i...\n", master->index); @@ -378,10 +355,12 @@ /*****************************************************************************/ /** - Gibt Frame-Inhalte zwecks Debugging aus. -*/ - -void ec_print_data(const uint8_t *data, size_t size) + Outputs frame contents for debugging purposes. +*/ + +void ec_print_data(const uint8_t *data, /**< pointer to data */ + size_t size /**< number of bytes to output */ + ) { unsigned int i; @@ -399,12 +378,12 @@ /*****************************************************************************/ /** - Gibt Frame-Inhalte zwecks Debugging aus, differentiell. -*/ - -void ec_print_data_diff(const uint8_t *d1, /**< Daten 1 */ - const uint8_t *d2, /**< Daten 2 */ - size_t size /** Anzahl Bytes */ + Outputs frame contents and differences for debugging purposes. +*/ + +void ec_print_data_diff(const uint8_t *d1, /**< first data */ + const uint8_t *d2, /**< second data */ + size_t size /** number of bytes to output */ ) { unsigned int i; @@ -434,9 +413,3 @@ EXPORT_SYMBOL(ecrt_release_master); /*****************************************************************************/ - -/* Emacs-Konfiguration -;;; Local Variables: *** -;;; c-basic-offset:4 *** -;;; End: *** -*/ diff -r c21e7c12dd50 -r 674071846ee3 master/slave.c --- a/master/slave.c Thu Apr 20 13:19:36 2006 +0000 +++ b/master/slave.c Thu Apr 20 13:31:31 2006 +0000 @@ -2,7 +2,7 @@ * * s l a v e . c * - * Methoden für einen EtherCAT-Slave. + * EtherCAT slave methods. * * $Id$ * @@ -63,13 +63,14 @@ /*****************************************************************************/ /** - EtherCAT-Slave-Konstruktor. -*/ - -int ec_slave_init(ec_slave_t *slave, /**< EtherCAT-Slave */ - ec_master_t *master, /**< EtherCAT-Master */ - uint16_t ring_position, /**< Ringposition */ - uint16_t station_address /**< Programmierte Adresse */ + Slave constructor. + \return 0 in case of success, else < 0 +*/ + +int ec_slave_init(ec_slave_t *slave, /**< EtherCAT slave */ + ec_master_t *master, /**< EtherCAT master */ + uint16_t ring_position, /**< ring position */ + uint16_t station_address /**< station address to configure */ ) { unsigned int i; @@ -77,7 +78,7 @@ slave->ring_position = ring_position; slave->station_address = station_address; - // Init kobject and add it to the hierarchy + // init kobject and add it to the hierarchy memset(&slave->kobj, 0x00, sizeof(struct kobject)); kobject_init(&slave->kobj); slave->kobj.ktype = &ktype_ec_slave; @@ -133,10 +134,10 @@ /*****************************************************************************/ /** - EtherCAT-Slave-Destruktor. -*/ - -void ec_slave_clear(struct kobject *kobj /**< KObject des Slaves */) + Slave destructor. +*/ + +void ec_slave_clear(struct kobject *kobj /**< kobject of the slave */) { ec_slave_t *slave; ec_eeprom_string_t *string, *next_str; @@ -148,24 +149,24 @@ slave = container_of(kobj, ec_slave_t, kobj); - // Alle Strings freigeben + // free all string objects list_for_each_entry_safe(string, next_str, &slave->eeprom_strings, list) { list_del(&string->list); kfree(string); } - // Alle Sync-Manager freigeben + // free all sync managers list_for_each_entry_safe(sync, next_sync, &slave->eeprom_syncs, list) { list_del(&sync->list); kfree(sync); } - // Alle PDOs freigeben + // free all PDOs list_for_each_entry_safe(pdo, next_pdo, &slave->eeprom_pdos, list) { list_del(&pdo->list); if (pdo->name) kfree(pdo->name); - // Alle Entries innerhalb eines PDOs freigeben + // free all PDO entries list_for_each_entry_safe(entry, next_ent, &pdo->entries, list) { list_del(&entry->list); if (entry->name) kfree(entry->name); @@ -179,12 +180,12 @@ if (slave->eeprom_group) kfree(slave->eeprom_group); if (slave->eeprom_desc) kfree(slave->eeprom_desc); - // Alle SDOs freigeben + // free all SDOs list_for_each_entry_safe(sdo, next_sdo, &slave->sdo_dictionary, list) { list_del(&sdo->list); if (sdo->name) kfree(sdo->name); - // Alle Entries freigeben + // free all SDO entries list_for_each_entry_safe(en, next_en, &sdo->entries, list) { list_del(&en->list); kfree(en); @@ -198,12 +199,11 @@ /*****************************************************************************/ /** - Liest alle benötigten Informationen aus einem Slave. - - \return 0 wenn alles ok, < 0 bei Fehler. -*/ - -int ec_slave_fetch(ec_slave_t *slave /**< EtherCAT-Slave */) + Reads all necessary information from a slave. + \return 0 in case of success, else < 0 +*/ + +int ec_slave_fetch(ec_slave_t *slave /**< EtherCAT slave */) { ec_command_t *command; unsigned int i; @@ -211,7 +211,7 @@ command = &slave->master->simple_command; - // Read base data + // read base data if (ec_command_nprd(command, slave->station_address, 0x0000, 6)) return -1; if (unlikely(ec_master_simple_io(slave->master, command))) { EC_ERR("Reading base data from slave %i failed!\n", @@ -228,7 +228,7 @@ if (slave->base_fmmu_count > EC_MAX_FMMUS) slave->base_fmmu_count = EC_MAX_FMMUS; - // Read DL status + // read data link status if (ec_command_nprd(command, slave->station_address, 0x0110, 2)) return -1; if (unlikely(ec_master_simple_io(slave->master, command))) { EC_ERR("Reading DL status from slave %i failed!\n", @@ -243,7 +243,7 @@ slave->dl_signal[i] = dl_status & (1 << (9 + i * 2)) ? 1 : 0; } - // Read EEPROM data + // read EEPROM data if (ec_slave_sii_read16(slave, 0x0004, &slave->sii_alias)) return -1; if (ec_slave_sii_read32(slave, 0x0008, &slave->sii_vendor_id)) @@ -276,18 +276,16 @@ /*****************************************************************************/ /** - Liest 16 Bit aus dem Slave-Information-Interface - eines EtherCAT-Slaves. - - \return 0 bei Erfolg, sonst < 0 + Reads 16 bit from the slave information interface (SII). + \return 0 in case of success, else < 0 */ int ec_slave_sii_read16(ec_slave_t *slave, - /**< EtherCAT-Slave */ + /**< EtherCAT slave */ uint16_t offset, - /**< Adresse des zu lesenden SII-Registers */ + /**< address of the SII register to read */ uint16_t *target - /**< Speicher für Wert (16-Bit) */ + /**< target memory */ ) { ec_command_t *command; @@ -295,7 +293,7 @@ command = &slave->master->simple_command; - // Initiate read operation + // initiate read operation if (ec_command_npwr(command, slave->station_address, 0x502, 6)) return -1; EC_WRITE_U8 (command->data, 0x00); // read-only access EC_WRITE_U8 (command->data + 1, 0x01); // request read operation @@ -305,10 +303,6 @@ return -1; } - // Der Slave legt die Informationen des Slave-Information-Interface - // in das Datenregister und löscht daraufhin ein Busy-Bit. Solange - // den Status auslesen, bis das Bit weg ist. - start = get_cycles(); timeout = (cycles_t) 100 * cpu_khz; // 100ms @@ -326,6 +320,7 @@ end = get_cycles(); + // check for "busy bit" if (likely((EC_READ_U8(command->data + 1) & 0x81) == 0)) { *target = EC_READ_U16(command->data + 6); return 0; @@ -341,18 +336,16 @@ /*****************************************************************************/ /** - Liest 32 Bit aus dem Slave-Information-Interface - eines EtherCAT-Slaves. - - \return 0 bei Erfolg, sonst < 0 + Reads 32 bit from the slave information interface (SII). + \return 0 in case of success, else < 0 */ int ec_slave_sii_read32(ec_slave_t *slave, - /**< EtherCAT-Slave */ + /**< EtherCAT slave */ uint16_t offset, - /**< Adresse des zu lesenden SII-Registers */ + /**< address of the SII register to read */ uint32_t *target - /**< Speicher für Wert (32-Bit) */ + /**< target memory */ ) { ec_command_t *command; @@ -360,7 +353,7 @@ command = &slave->master->simple_command; - // Initiate read operation + // initiate read operation if (ec_command_npwr(command, slave->station_address, 0x502, 6)) return -1; EC_WRITE_U8 (command->data, 0x00); // read-only access EC_WRITE_U8 (command->data + 1, 0x01); // request read operation @@ -370,10 +363,6 @@ return -1; } - // Der Slave legt die Informationen des Slave-Information-Interface - // in das Datenregister und löscht daraufhin ein Busy-Bit. Solange - // den Status auslesen, bis das Bit weg ist. - start = get_cycles(); timeout = (cycles_t) 100 * cpu_khz; // 100ms @@ -391,6 +380,7 @@ end = get_cycles(); + // check "busy bit" if (likely((EC_READ_U8(command->data + 1) & 0x81) == 0)) { *target = EC_READ_U32(command->data + 6); return 0; @@ -406,18 +396,16 @@ /*****************************************************************************/ /** - Schreibt 16 Bit Daten in das Slave-Information-Interface - eines EtherCAT-Slaves. - - \return 0 bei Erfolg, sonst < 0 + Writes 16 bit of data to the slave information interface (SII). + \return 0 in case of success, else < 0 */ int ec_slave_sii_write16(ec_slave_t *slave, - /**< EtherCAT-Slave */ + /**< EtherCAT slave */ uint16_t offset, - /**< Adresse des zu lesenden SII-Registers */ + /**< address of the SII register to write */ uint16_t value - /**< Zu schreibender Wert */ + /**< new value */ ) { ec_command_t *command; @@ -428,7 +416,7 @@ EC_INFO("SII-write (slave %i, offset 0x%04X, value 0x%04X)\n", slave->ring_position, offset, value); - // Initiate write operation + // initiate write operation if (ec_command_npwr(command, slave->station_address, 0x502, 8)) return -1; EC_WRITE_U8 (command->data, 0x01); // enable write access EC_WRITE_U8 (command->data + 1, 0x02); // request write operation @@ -439,10 +427,6 @@ return -1; } - // Der Slave legt die Informationen des Slave-Information-Interface - // in das Datenregister und löscht daraufhin ein Busy-Bit. Solange - // den Status auslesen, bis das Bit weg ist. - start = get_cycles(); timeout = (cycles_t) 100 * cpu_khz; // 100ms @@ -460,6 +444,7 @@ end = get_cycles(); + // check "busy bit" if (likely((EC_READ_U8(command->data + 1) & 0x82) == 0)) { if (EC_READ_U8(command->data + 1) & 0x40) { EC_ERR("SII-write failed!\n"); @@ -481,12 +466,11 @@ /*****************************************************************************/ /** - Holt Daten aus dem EEPROM. - - \return 0, wenn alles ok, sonst < 0 -*/ - -int ec_slave_fetch_categories(ec_slave_t *slave /**< EtherCAT-Slave */) + Fetches data from slave's EEPROM. + \return 0 in case of success, else < 0 +*/ + +int ec_slave_fetch_categories(ec_slave_t *slave /**< EtherCAT slave */) { uint16_t word_offset, cat_type, word_count; uint32_t value; @@ -507,13 +491,13 @@ goto out_free; } - // Last category? + // last category? if ((value & 0xFFFF) == 0xFFFF) break; cat_type = value & 0x7FFF; word_count = (value >> 16) & 0xFFFF; - // Fetch category data + // fetch category data for (i = 0; i < word_count; i++) { if (ec_slave_sii_read32(slave, word_offset + 2 + i, &value)) { EC_ERR("Unable to read category data word %i.\n", i); @@ -574,13 +558,12 @@ /*****************************************************************************/ /** - Holt die Daten einer String-Kategorie. - - \return 0 wenn alles ok, sonst < 0 -*/ - -int ec_slave_fetch_strings(ec_slave_t *slave, /**< EtherCAT-Slave */ - const uint8_t *data /**< Kategoriedaten */ + Fetches data from a STRING category. + \return 0 in case of success, else < 0 +*/ + +int ec_slave_fetch_strings(ec_slave_t *slave, /**< EtherCAT slave */ + const uint8_t *data /**< category data */ ) { unsigned int string_count, i; @@ -592,7 +575,7 @@ offset = 1; for (i = 0; i < string_count; i++) { size = data[offset]; - // Speicher für String-Objekt und Daten in einem Rutsch allozieren + // allocate memory for string structure and data at a single blow if (!(string = (ec_eeprom_string_t *) kmalloc(sizeof(ec_eeprom_string_t) + size + 1, GFP_KERNEL))) { EC_ERR("Failed to allocate string memory.\n"); @@ -613,11 +596,12 @@ /*****************************************************************************/ /** - Holt die Daten einer General-Kategorie. -*/ - -int ec_slave_fetch_general(ec_slave_t *slave, /**< EtherCAT-Slave */ - const uint8_t *data /**< Kategorie-Daten */ + Fetches data from a GENERAL category. + \return 0 in case of success, else < 0 +*/ + +int ec_slave_fetch_general(ec_slave_t *slave, /**< EtherCAT slave */ + const uint8_t *data /**< category data */ ) { unsigned int i; @@ -630,7 +614,8 @@ return -1; for (i = 0; i < 4; i++) - slave->sii_physical_layer[i] = (data[4] & (0x03 << (i * 2))) >> (i * 2); + slave->sii_physical_layer[i] = + (data[4] & (0x03 << (i * 2))) >> (i * 2); return 0; } @@ -638,18 +623,19 @@ /*****************************************************************************/ /** - Holt die Daten einer Sync-Manager-Kategorie. -*/ - -int ec_slave_fetch_sync(ec_slave_t *slave, /**< EtherCAT-Slave */ - const uint8_t *data, /**< Kategorie-Daten */ - size_t word_count /**< Anzahl Words */ + Fetches data from a SYNC MANAGER category. + \return 0 in case of success, else < 0 +*/ + +int ec_slave_fetch_sync(ec_slave_t *slave, /**< EtherCAT slave */ + const uint8_t *data, /**< category data */ + size_t word_count /**< number of words */ ) { unsigned int sync_count, i; ec_eeprom_sync_t *sync; - sync_count = word_count / 4; // Sync-Manager-Strunktur ist 4 Worte lang + sync_count = word_count / 4; // sync manager struct is 4 words long for (i = 0; i < sync_count; i++, data += 8) { if (!(sync = (ec_eeprom_sync_t *) @@ -673,13 +659,14 @@ /*****************************************************************************/ /** - Holt die Daten einer TXPDO-Kategorie. -*/ - -int ec_slave_fetch_pdo(ec_slave_t *slave, /**< EtherCAT-Slave */ - const uint8_t *data, /**< Kategorie-Daten */ - size_t word_count, /**< Anzahl Worte */ - ec_pdo_type_t pdo_type /**< PDO-Typ */ + Fetches data from a [RT]XPDO category. + \return 0 in case of success, else < 0 +*/ + +int ec_slave_fetch_pdo(ec_slave_t *slave, /**< EtherCAT slave */ + const uint8_t *data, /**< category data */ + size_t word_count, /**< number of words */ + ec_pdo_type_t pdo_type /**< PDO type */ ) { ec_eeprom_pdo_t *pdo; @@ -733,7 +720,8 @@ /*****************************************************************************/ /** - Durchsucht die temporären Strings und dupliziert den gefundenen String. + Searches the string list for an index and allocates a new string. + \return 0 in case of success, else < 0 */ int ec_slave_locate_string(ec_slave_t *slave, unsigned int index, char **ptr) @@ -778,13 +766,11 @@ /*****************************************************************************/ /** - Bestätigt einen Fehler beim Zustandswechsel. -*/ - -void ec_slave_state_ack(ec_slave_t *slave, - /**< Slave, dessen Zustand geändert werden soll */ - uint8_t state - /**< Alter Zustand */ + Acknowledges an error after a state transition. +*/ + +void ec_slave_state_ack(ec_slave_t *slave, /**< EtherCAT slave */ + uint8_t state /**< previous state */ ) { ec_command_t *command; @@ -805,7 +791,7 @@ while (1) { - udelay(100); // Dem Slave etwas Zeit lassen... + udelay(100); // wait a little bit... if (ec_command_nprd(command, slave->station_address, 0x0130, 2)) return; @@ -835,12 +821,11 @@ /** Reads the AL status code of a slave and displays it. - If the AL status code is not supported, or if no error occurred (both resulting in code=0), nothing is displayed. */ -void ec_slave_read_al_status_code(ec_slave_t *slave /**< EtherCAT-Slave */) +void ec_slave_read_al_status_code(ec_slave_t *slave /**< EtherCAT slave */) { ec_command_t *command; uint16_t code; @@ -871,15 +856,12 @@ /*****************************************************************************/ /** - Ändert den Zustand eines Slaves. - - \return 0 bei Erfolg, sonst < 0 -*/ - -int ec_slave_state_change(ec_slave_t *slave, - /**< Slave, dessen Zustand geändert werden soll */ - uint8_t state - /**< Neuer Zustand */ + Does a state transition. + \return 0 in case of success, else < 0 +*/ + +int ec_slave_state_change(ec_slave_t *slave, /**< EtherCAT slave */ + uint8_t state /**< new state */ ) { ec_command_t *command; @@ -900,7 +882,7 @@ while (1) { - udelay(100); // Dem Slave etwas Zeit lassen... + udelay(100); // wait a little bit if (ec_command_nprd(command, slave->station_address, 0x0130, 2)) return -1; @@ -912,7 +894,7 @@ end = get_cycles(); - if (unlikely(EC_READ_U8(command->data) & 0x10)) { // State change error + if (unlikely(EC_READ_U8(command->data) & 0x10)) { // state change error EC_ERR("Failed to set state 0x%02X - Slave %i refused state change" " (code 0x%02X)!\n", state, slave->ring_position, EC_READ_U8(command->data)); @@ -922,10 +904,8 @@ return -1; } - if (likely(EC_READ_U8(command->data) == (state & 0x0F))) { - // State change successful - return 0; - } + if (likely(EC_READ_U8(command->data) == (state & 0x0F))) + return 0; // state change successful if (unlikely((end - start) >= timeout)) { EC_ERR("Failed to check state 0x%02X of slave %i - Timeout!\n", @@ -938,31 +918,30 @@ /*****************************************************************************/ /** - Merkt eine FMMU-Konfiguration vor. - - Die FMMU wird so konfiguriert, dass sie den gesamten Datenbereich des - entsprechenden Sync-Managers abdeckt. Für jede Domäne werden separate - FMMUs konfiguriert. - - Wenn die entsprechende FMMU bereits konfiguriert ist, wird dies als - Erfolg zurückgegeben. - - \return 0 bei Erfolg, sonst < 0 -*/ - -int ec_slave_prepare_fmmu(ec_slave_t *slave, /**< EtherCAT-Slave */ - const ec_domain_t *domain, /**< Domäne */ - const ec_sync_t *sync /**< Sync-Manager */ + Prepares an FMMU configuration. + Configuration data for the FMMU is saved in the slave structure and is + written to the slave in ecrt_master_activate(). + The FMMU configuration is done in a way, that the complete data range + of the corresponding sync manager is covered. Seperate FMMUs arce configured + for each domain. + If the FMMU configuration is already prepared, the function returns with + success. + \return 0 in case of success, else < 0 +*/ + +int ec_slave_prepare_fmmu(ec_slave_t *slave, /**< EtherCAT slave */ + const ec_domain_t *domain, /**< domain */ + const ec_sync_t *sync /**< sync manager */ ) { unsigned int i; - // FMMU schon vorgemerkt? + // FMMU configuration already prepared? for (i = 0; i < slave->fmmu_count; i++) if (slave->fmmus[i].domain == domain && slave->fmmus[i].sync == sync) return 0; - // Neue FMMU reservieren... + // reserve new FMMU... if (slave->fmmu_count >= slave->base_fmmu_count) { EC_ERR("Slave %i FMMU limit reached!\n", slave->ring_position); @@ -981,16 +960,15 @@ /*****************************************************************************/ /** - Gibt alle Informationen über einen EtherCAT-Slave aus. - + Outputs all information about a certain slave. Verbosity: - 0 - Nur Slavetypen und Adressen - 1 - mit EEPROM-Informationen - >1 - mit SDO-Dictionaries -*/ - -void ec_slave_print(const ec_slave_t *slave, /**< EtherCAT-Slave */ - unsigned int verbosity /**< Geschwätzigkeit */ + - 0: Only slave types and addresses + - 1: with EEPROM information + - >1: with SDO dictionaries +*/ + +void ec_slave_print(const ec_slave_t *slave, /**< EtherCAT slave */ + unsigned int verbosity /**< verbosity level */ ) { ec_eeprom_sync_t *sync; @@ -1146,12 +1124,11 @@ /*****************************************************************************/ /** - Gibt die Zählerstände der CRC-Fault-Counter aus und setzt diese zurück. - - \return 0 bei Erfolg, sonst < 0 -*/ - -int ec_slave_check_crc(ec_slave_t *slave /**< EtherCAT-Slave */) + Outputs the values of the CRC faoult counters and resets them. + \return 0 in case of success, else < 0 +*/ + +int ec_slave_check_crc(ec_slave_t *slave /**< EtherCAT slave */) { ec_command_t *command; @@ -1164,8 +1141,7 @@ return -1; } - // No CRC faults. - if (!EC_READ_U32(command->data)) return 0; + if (!EC_READ_U32(command->data)) return 0; // no CRC faults if (EC_READ_U8(command->data)) EC_WARN("%3i RX-error%s on slave %i, channel A.\n", @@ -1188,7 +1164,7 @@ EC_READ_U8(command->data + 3) == 1 ? "" : "s", slave->ring_position); - // Reset CRC counters + // reset CRC counters if (ec_command_npwr(command, slave->station_address, 0x0300, 4)) return -1; EC_WRITE_U32(command->data, 0x00000000); if (unlikely(ec_master_simple_io(slave->master, command))) { @@ -1203,12 +1179,12 @@ /*****************************************************************************/ /** - Schreibt den "Configured station alias". - \return 0, wenn alles ok, sonst < 0 -*/ - -int ecrt_slave_write_alias(ec_slave_t *slave, /** EtherCAT-Slave */ - uint16_t alias /** Neuer Alias */ + Writes the "configured station alias" to the slave's EEPROM. + \return 0 in case of success, else < 0 +*/ + +int ecrt_slave_write_alias(ec_slave_t *slave, /** EtherCAT slave */ + uint16_t alias /** new alias */ ) { return ec_slave_sii_write16(slave, 0x0004, alias); @@ -1217,14 +1193,13 @@ /*****************************************************************************/ /** - Formatiert Attribut-Daten für lesenden Zugriff im SysFS - - \return Anzahl Bytes im Speicher -*/ - -ssize_t ec_show_slave_attribute(struct kobject *kobj, /**< KObject */ - struct attribute *attr, /**< Attribut */ - char *buffer /**< Speicher für die Daten */ + Formats attribute data for SysFS read access. + \return number of bytes to read +*/ + +ssize_t ec_show_slave_attribute(struct kobject *kobj, /**< slave's kobject */ + struct attribute *attr, /**< attribute */ + char *buffer /**< memory to store data */ ) { ec_slave_t *slave = container_of(kobj, ec_slave_t, kobj); @@ -1287,10 +1262,3 @@ EXPORT_SYMBOL(ecrt_slave_write_alias); /*****************************************************************************/ - -/* Emacs-Konfiguration -;;; Local Variables: *** -;;; c-basic-offset:4 *** -;;; End: *** -*/ - diff -r c21e7c12dd50 -r 674071846ee3 master/slave.h --- a/master/slave.h Thu Apr 20 13:19:36 2006 +0000 +++ b/master/slave.h Thu Apr 20 13:31:31 2006 +0000 @@ -2,7 +2,7 @@ * * s l a v e . h * - * Struktur für einen EtherCAT-Slave. + * EtherCAT stave structure. * * $Id$ * @@ -21,30 +21,30 @@ /*****************************************************************************/ /** - Zustand eines EtherCAT-Slaves. + State of an EtherCAT slave. */ typedef enum { EC_SLAVE_STATE_UNKNOWN = 0x00, - /**< Status unbekannt */ + /**< unknown state */ EC_SLAVE_STATE_INIT = 0x01, - /**< Init-Zustand (Keine Mailbox-Kommunikation, Kein I/O) */ + /**< INIT state (no mailbox communication, no IO) */ EC_SLAVE_STATE_PREOP = 0x02, - /**< Pre-Operational (Mailbox-Kommunikation, Kein I/O) */ + /**< PREOP state (mailbox communication, no IO) */ EC_SLAVE_STATE_SAVEOP = 0x04, - /**< Save-Operational (Mailbox-Kommunikation und Input Update) */ + /**< SAVEOP (mailbox communication and input update) */ EC_SLAVE_STATE_OP = 0x08, - /**< Operational, (Mailbox-Kommunikation und Input/Output Update) */ + /**< OP (mailbox communication and input/output update) */ EC_ACK = 0x10 - /**< Acknoledge-Bit beim Zustandswechsel (kein eigener Zustand) */ + /**< Acknoledge bit (no state) */ } ec_slave_state_t; /*****************************************************************************/ /** - Unterstützte Mailbox-Protokolle. + Supported mailbox protocols. */ enum @@ -60,124 +60,124 @@ /*****************************************************************************/ /** - FMMU-Konfiguration. -*/ - -typedef struct -{ - const ec_domain_t *domain; - const ec_sync_t *sync; - uint32_t logical_start_address; + FMMU configuration. +*/ + +typedef struct +{ + const ec_domain_t *domain; /**< domain */ + const ec_sync_t *sync; /**< sync manager */ + uint32_t logical_start_address; /**< logical start address */ } ec_fmmu_t; /*****************************************************************************/ /** - String im EEPROM eines EtherCAT-Slaves. -*/ - -typedef struct -{ - struct list_head list; - size_t size; - char *data; + String object (EEPROM). +*/ + +typedef struct +{ + struct list_head list; /**< list item */ + size_t size; /**< size in bytes */ + char *data; /**< string data */ } ec_eeprom_string_t; /*****************************************************************************/ /** - Sync-Manager-Konfiguration laut EEPROM. -*/ - -typedef struct -{ - struct list_head list; - unsigned int index; - uint16_t physical_start_address; - uint16_t length; - uint8_t control_register; - uint8_t enable; + Sync manager configuration (EEPROM). +*/ + +typedef struct +{ + struct list_head list; /**< list item */ + unsigned int index; /**< sync manager index */ + uint16_t physical_start_address; /**< physical start address */ + uint16_t length; /**< data length in bytes */ + uint8_t control_register; /**< control register value */ + uint8_t enable; /**< enable bit */ } ec_eeprom_sync_t; /*****************************************************************************/ /** - PDO-Typ. + PDO type. */ typedef enum { - EC_RX_PDO, - EC_TX_PDO + EC_RX_PDO, /**< Reveive PDO */ + EC_TX_PDO /**< Transmit PDO */ } ec_pdo_type_t; /*****************************************************************************/ /** - PDO-Beschreibung im EEPROM. -*/ - -typedef struct -{ - struct list_head list; - ec_pdo_type_t type; - uint16_t index; - uint8_t sync_manager; - char *name; - struct list_head entries; + PDO description (EEPROM). +*/ + +typedef struct +{ + struct list_head list; /**< list item */ + ec_pdo_type_t type; /**< PDO type */ + uint16_t index; /**< PDO index */ + uint8_t sync_manager; /**< assigned sync manager */ + char *name; /**< PDO name */ + struct list_head entries; /**< entry list */ } ec_eeprom_pdo_t; /*****************************************************************************/ /** - PDO-Entry-Beschreibung im EEPROM. -*/ - -typedef struct -{ - struct list_head list; - uint16_t index; - uint8_t subindex; - char *name; - uint8_t bit_length; + PDO entry description (EEPROM). +*/ + +typedef struct +{ + struct list_head list; /**< list item */ + uint16_t index; /**< PDO index */ + uint8_t subindex; /**< entry subindex */ + char *name; /**< entry name */ + uint8_t bit_length; /**< entry length in bit */ } ec_eeprom_pdo_entry_t; /*****************************************************************************/ /** - CANopen-SDO. -*/ - -typedef struct -{ - struct list_head list; - uint16_t index; + CANopen SDO. +*/ + +typedef struct +{ + struct list_head list; /**< list item */ + uint16_t index; /**< SDO index */ //uint16_t type; - uint8_t object_code; - char *name; - struct list_head entries; + uint8_t object_code; /**< object code */ + char *name; /**< SDO name */ + struct list_head entries; /**< entry list */ } ec_sdo_t; /*****************************************************************************/ /** - CANopen-SDO-Entry. -*/ - -typedef struct -{ - struct list_head list; - uint8_t subindex; - uint16_t data_type; - uint16_t bit_length; - char *name; + CANopen SDO entry. +*/ + +typedef struct +{ + struct list_head list; /**< list item */ + uint8_t subindex; /**< entry subindex */ + uint16_t data_type; /**< entry data type */ + uint16_t bit_length; /**< entry length in bit */ + char *name; /**< entry name */ } ec_sdo_entry_t; @@ -189,69 +189,68 @@ struct ec_slave { - struct list_head list; /**< Noetig fuer Slave-Liste im Master */ - struct kobject kobj; /**< Kernel-Object */ - ec_master_t *master; /**< EtherCAT-Master, zu dem der Slave gehört. */ - - // Addresses - uint16_t ring_position; /**< Position des Slaves im Bus */ - uint16_t station_address; /**< Konfigurierte Slave-Adresse */ - uint16_t coupler_index; /**< Letzter Buskoppler */ - uint16_t coupler_subindex; /**< Index hinter letztem Buskoppler */ - - // Base data - uint8_t base_type; /**< Slave-Typ */ - uint8_t base_revision; /**< Revision */ - uint16_t base_build; /**< Build-Nummer */ - uint16_t base_fmmu_count; /**< Anzahl unterstützter FMMUs */ - uint16_t base_sync_count; /**< Anzahl unterstützter Sync-Manager */ - - // Data link status - uint8_t dl_link[4]; /**< Verbindung erkannt */ - uint8_t dl_loop[4]; /**< Loop geschlossen */ - uint8_t dl_signal[4]; /**< Signal an RX-Seite erkannt */ - - // Slave information interface - uint16_t sii_alias; /**< Configured station alias */ - uint32_t sii_vendor_id; /**< Identifikationsnummer des Herstellers */ - uint32_t sii_product_code; /**< Herstellerspezifischer Produktcode */ - uint32_t sii_revision_number; /**< Revisionsnummer */ - uint32_t sii_serial_number; /**< Seriennummer der Klemme */ - uint16_t sii_rx_mailbox_offset; /**< Adresse der Mailbox (Master->Slave) */ - uint16_t sii_rx_mailbox_size; /**< Adresse der Mailbox (Master->Slave) */ - uint16_t sii_tx_mailbox_offset; /**< Adresse der Mailbox (Slave->Master) */ - uint16_t sii_tx_mailbox_size; /**< Adresse der Mailbox (Slave->Master) */ - uint16_t sii_mailbox_protocols; /**< Unterstützte Mailbox-Protokolle */ - uint8_t sii_physical_layer[4]; /**< Uebertragungsarten der Ports */ - - const ec_slave_type_t *type; /**< Zeiger auf die Beschreibung - des Slave-Typs */ - - uint8_t registered; /**< Der Slave wurde registriert */ - - ec_fmmu_t fmmus[EC_MAX_FMMUS]; /**< FMMU-Konfigurationen */ - uint8_t fmmu_count; /**< Wieviele FMMUs schon benutzt sind. */ - - struct list_head eeprom_strings; /**< Strings im EEPROM */ - struct list_head eeprom_syncs; /**< Syncmanager-Konfigurationen (EEPROM) */ - struct list_head eeprom_pdos; /**< PDO-Beschreibungen im EEPROM */ - - char *eeprom_name; /**< Slave-Name laut Hersteller */ - char *eeprom_group; /**< Slave-Beschreibung laut Hersteller */ - char *eeprom_desc; /**< Slave-Beschreibung laut Hersteller */ - - struct list_head sdo_dictionary; /**< SDO-Verzeichnis des Slaves */ - - ec_command_t mbox_command; /**< Kommando für Mailbox-Kommunikation */ + struct list_head list; /**< list item */ + struct kobject kobj; /**< kobject */ + ec_master_t *master; /**< master owning the slave */ + + // addresses + uint16_t ring_position; /**< ring position */ + uint16_t station_address; /**< configured station address */ + uint16_t coupler_index; /**< index of the last bus coupler */ + uint16_t coupler_subindex; /**< index of this slave after last coupler */ + + // base data + uint8_t base_type; /**< slave type */ + uint8_t base_revision; /**< revision */ + uint16_t base_build; /**< build number */ + uint16_t base_fmmu_count; /**< number of supported FMMUs */ + uint16_t base_sync_count; /**< number of supported sync managers */ + + // data link status + uint8_t dl_link[4]; /**< link detected */ + uint8_t dl_loop[4]; /**< loop closed */ + uint8_t dl_signal[4]; /**< detected signal on RX port */ + + // slave information interface + uint16_t sii_alias; /**< configured station alias */ + uint32_t sii_vendor_id; /**< vendor id */ + uint32_t sii_product_code; /**< vendor's product code */ + uint32_t sii_revision_number; /**< revision number */ + uint32_t sii_serial_number; /**< serial number */ + uint16_t sii_rx_mailbox_offset; /**< mailbox address (master to slave) */ + uint16_t sii_rx_mailbox_size; /**< mailbox size (master to slave) */ + uint16_t sii_tx_mailbox_offset; /**< mailbox address (slave to master) */ + uint16_t sii_tx_mailbox_size; /**< mailbox size (slave to master) */ + uint16_t sii_mailbox_protocols; /**< supported mailbox protocols */ + uint8_t sii_physical_layer[4]; /**< port media */ + + const ec_slave_type_t *type; /**< pointer to slave type object */ + + uint8_t registered; /**< true, if slave has been registered */ + + ec_fmmu_t fmmus[EC_MAX_FMMUS]; /**< FMMU configurations */ + uint8_t fmmu_count; /**< number of FMMUs used */ + + struct list_head eeprom_strings; /**< EEPROM STRING categories */ + struct list_head eeprom_syncs; /**< EEPROM SYNC MANAGER categories */ + struct list_head eeprom_pdos; /**< EEPROM [RT]XPDO categories */ + + char *eeprom_name; /**< slave name acc. to EEPROM */ + char *eeprom_group; /**< slave group acc. to EEPROM */ + char *eeprom_desc; /**< slave description acc. to EEPROM */ + + struct list_head sdo_dictionary; /**< SDO directory list */ + + ec_command_t mbox_command; /**< mailbox command */ }; /*****************************************************************************/ -// Slave construction/destruction +// slave construction/destruction int ec_slave_init(ec_slave_t *, ec_master_t *, uint16_t, uint16_t); void ec_slave_clear(struct kobject *); -// Slave control +// slave control int ec_slave_fetch(ec_slave_t *); int ec_slave_sii_read16(ec_slave_t *, uint16_t, uint16_t *); int ec_slave_sii_read32(ec_slave_t *, uint16_t, uint32_t *); @@ -260,19 +259,13 @@ int ec_slave_prepare_fmmu(ec_slave_t *, const ec_domain_t *, const ec_sync_t *); -// CANopen over EtherCAT +// CoE int ec_slave_fetch_sdo_list(ec_slave_t *); -// Misc +// misc. void ec_slave_print(const ec_slave_t *, unsigned int); int ec_slave_check_crc(ec_slave_t *); /*****************************************************************************/ #endif - -/* Emacs-Konfiguration -;;; Local Variables: *** -;;; c-basic-offset:4 *** -;;; End: *** -*/ diff -r c21e7c12dd50 -r 674071846ee3 master/types.c --- a/master/types.c Thu Apr 20 13:19:36 2006 +0000 +++ b/master/types.c Thu Apr 20 13:31:31 2006 +0000 @@ -2,7 +2,7 @@ * * t y p e s . c * - * EtherCAT-Slave-Typen. + * EtherCAT slave descriptions. * * $Id$ * @@ -18,36 +18,34 @@ const ec_sync_t mailbox_sm0 = {0x1800, 246, 0x26, {NULL}}; const ec_sync_t mailbox_sm1 = {0x18F6, 246, 0x22, {NULL}}; -/*****************************************************************************/ - -/* Klemmen-Objekte */ - -/*****************************************************************************/ +/****************************************************************************** + * slave objects + *****************************************************************************/ const ec_slave_type_t Beckhoff_EK1100 = { "Beckhoff", "EK1100", "Bus Coupler", EC_TYPE_BUS_COUPLER, - {NULL} // Keine Sync-Manager + {NULL} // no sync managers }; /*****************************************************************************/ const ec_slave_type_t Beckhoff_EK1110 = { "Beckhoff", "EK1110", "Extension terminal", EC_TYPE_NORMAL, - {NULL} // Keine Sync-Manager + {NULL} // no sync managers }; /*****************************************************************************/ const ec_slave_type_t Beckhoff_BK1120 = { "Beckhoff", "BK1120", "KBUS Coupler", EC_TYPE_NORMAL, - {NULL} // Keine Sync-Manager + {NULL} // no sync managers }; /*****************************************************************************/ const ec_field_t el1014_in = {"InputValue", 1}; -const ec_sync_t el1014_sm0 = { // Inputs +const ec_sync_t el1014_sm0 = { // inputs 0x1000, 1, 0x00, {&el1014_in, NULL} }; @@ -195,15 +193,10 @@ /*****************************************************************************/ /** - Beziehung zwischen Identifikationsnummern und Klemmen-Objekt. - - Diese Tabelle stellt die Beziehungen zwischen bestimmten Kombinationen - aus Vendor-IDs und Product-Codes und der entsprechenden Klemme her. - Neue Klemmen müssen hier eingetragen werden. + Mapping between vendor IDs and product codes <=> slave objects. */ -ec_slave_ident_t slave_idents[] = -{ +ec_slave_ident_t slave_idents[] = { {0x00000002, 0x03F63052, &Beckhoff_EL1014}, {0x00000002, 0x044C2C52, &Beckhoff_EK1100}, {0x00000002, 0x04562C52, &Beckhoff_EK1110}, @@ -222,9 +215,3 @@ }; /*****************************************************************************/ - -/* Emacs-Konfiguration -;;; Local Variables: *** -;;; c-basic-offset:4 *** -;;; End: *** -*/ diff -r c21e7c12dd50 -r 674071846ee3 master/types.h --- a/master/types.h Thu Apr 20 13:19:36 2006 +0000 +++ b/master/types.h Thu Apr 20 13:31:31 2006 +0000 @@ -2,7 +2,7 @@ * * t y p e s . h * - * EtherCAT-Slave-Typen. + * EtherCAT slave types. * * $Id$ * @@ -23,27 +23,27 @@ /*****************************************************************************/ /** - Besondere Slaves. + Special slaves. */ typedef enum { - EC_TYPE_NORMAL, - EC_TYPE_BUS_COUPLER, - EC_TYPE_EOE + EC_TYPE_NORMAL, /**< no special slave */ + EC_TYPE_BUS_COUPLER, /**< slave is a bus coupler */ + EC_TYPE_EOE /**< slave is an EoE switch */ } ec_special_type_t; /*****************************************************************************/ /** - Prozessdatenfeld. + Process data field. */ typedef struct { - const char *name; - size_t size; + const char *name; /**< field name */ + size_t size; /**< field size in bytes */ } ec_field_t; @@ -55,60 +55,45 @@ typedef struct { - uint16_t physical_start_address; - uint16_t size; - uint8_t control_byte; - const ec_field_t *fields[EC_MAX_FIELDS]; + uint16_t physical_start_address; /**< physical start address */ + uint16_t size; /**< size in bytes */ + uint8_t control_byte; /**< control register value */ + const ec_field_t *fields[EC_MAX_FIELDS]; /**< field array */ } ec_sync_t; /*****************************************************************************/ /** - Beschreibung eines EtherCAT-Slave-Typs. - - Diese Beschreibung dient zur Konfiguration einer bestimmten - Slave-Art. Sie enthält die Konfigurationsdaten für die - Slave-internen Sync-Manager und FMMUs. + Slave description type. */ typedef struct ec_slave_type { - const char *vendor_name; /**< Name des Herstellers */ - const char *product_name; /**< Name des Slaves-Typs */ - const char *description; /**< Genauere Beschreibung des Slave-Typs */ - ec_special_type_t special; /**< Spezieller Slave-Typ */ - const ec_sync_t *sync_managers[EC_MAX_SYNC]; /**< Sync-Manager - Konfigurationen */ + const char *vendor_name; /**< vendor name*/ + const char *product_name; /**< product name */ + const char *description; /**< free description */ + ec_special_type_t special; /**< special slave type? */ + const ec_sync_t *sync_managers[EC_MAX_SYNC]; /**< sync managers */ } ec_slave_type_t; /*****************************************************************************/ /** - Identifikation eines Slave-Typs. - - Diese Struktur wird zur 1:n-Zuordnung von Hersteller- und - Produktcodes zu den einzelnen Slave-Typen verwendet. + Slave type identification. */ -typedef struct slave_ident +typedef struct { - uint32_t vendor_id; /**< Hersteller-Code */ - uint32_t product_code; /**< Herstellerspezifischer Produktcode */ - const ec_slave_type_t *type; /**< Zeiger auf den entsprechenden Typ */ + uint32_t vendor_id; /**< vendor id */ + uint32_t product_code; /**< product code */ + const ec_slave_type_t *type; /**< associated slave description object */ } ec_slave_ident_t; -extern ec_slave_ident_t slave_idents[]; /**< Statisches Array der - Slave-Identifikationen */ +extern ec_slave_ident_t slave_idents[]; /**< array with slave descriptions */ /*****************************************************************************/ #endif - -/* Emacs-Konfiguration -;;; Local Variables: *** -;;; c-basic-offset:4 *** -;;; End: *** -*/ diff -r c21e7c12dd50 -r 674071846ee3 mini/Makefile --- a/mini/Makefile Thu Apr 20 13:19:36 2006 +0000 +++ b/mini/Makefile Thu Apr 20 13:31:31 2006 +0000 @@ -2,7 +2,7 @@ # # Makefile # -# Minimales EtherCAT-Modul +# Minimal EtherCAT module. # # $Id$ # @@ -11,7 +11,7 @@ ifneq ($(KERNELRELEASE),) #---------------------------------------------------------------- -# Kbuild-Abschnitt +# kbuild section #---------------------------------------------------------------- obj-m := ec_mini.o @@ -23,7 +23,7 @@ else #---------------------------------------------------------------- -# Default-Abschnitt +# default section #---------------------------------------------------------------- ifneq ($(wildcard ethercat.conf),) diff -r c21e7c12dd50 -r 674071846ee3 mini/mini.c --- a/mini/mini.c Thu Apr 20 13:19:36 2006 +0000 +++ b/mini/mini.c Thu Apr 20 13:31:31 2006 +0000 @@ -2,7 +2,7 @@ * * m i n i . c * - * Minimalmodul für EtherCAT + * Minimal module for EtherCAT. * * $Id$ * @@ -12,31 +12,28 @@ #include #include -#include "../include/ecrt.h" // Echtzeitschnittstelle +#include "../include/ecrt.h" // EtherCAT realtime interface #define ASYNC - -/*****************************************************************************/ - -#define ABTASTFREQUENZ 100 +#define FREQUENCY 100 + +/*****************************************************************************/ struct timer_list timer; -/*****************************************************************************/ - // EtherCAT ec_master_t *master = NULL; ec_domain_t *domain1 = NULL; -// Datenfelder +// data fields //void *r_ssi_input, *r_ssi_status, *r_4102[3]; -// Kanäle +// channels uint32_t k_pos; uint8_t k_stat; ec_field_init_t domain1_fields[] = { - {NULL, "1", "Beckhoff", "EL5001", "InputValue", 0}, + {NULL, "1", "Beckhoff", "EL5001", "InputValue", 0}, {NULL, "2", "Beckhoff", "EL4132", "OutputValue", 0}, {} }; @@ -48,22 +45,22 @@ static unsigned int counter = 0; #ifdef ASYNC - // Empfangen + // receive ecrt_master_async_receive(master); ecrt_domain_process(domain1); #else - // Senden und empfangen + // send and receive ecrt_domain_queue(domain1); ecrt_master_run(master); ecrt_master_sync_io(master); ecrt_domain_process(domain1); #endif - // Prozessdaten verarbeiten + // process data //k_pos = EC_READ_U32(r_ssi); #ifdef ASYNC - // Senden + // send ecrt_domain_queue(domain1); ecrt_master_run(master); ecrt_master_async_send(master); @@ -73,13 +70,13 @@ counter--; } else { - counter = ABTASTFREQUENZ; + counter = FREQUENCY; //printk(KERN_INFO "k_pos = %i\n", k_pos); //printk(KERN_INFO "k_stat = 0x%02X\n", k_stat); } - // Timer neu starten - timer.expires += HZ / ABTASTFREQUENZ; + // restart timer + timer.expires += HZ / FREQUENCY; add_timer(&timer); } @@ -153,14 +150,14 @@ #endif #ifdef ASYNC - // Einmal senden und warten... + // send once and wait... ecrt_master_prepare_async_io(master); #endif printk("Starting cyclic sample thread.\n"); init_timer(&timer); timer.function = run; - timer.expires = jiffies + 10; // Das erste Mal sofort feuern + timer.expires = jiffies + 10; add_timer(&timer); printk(KERN_INFO "=== Minimal EtherCAT environment started. ===\n"); @@ -203,8 +200,3 @@ /*****************************************************************************/ -/* Emacs-Konfiguration -;;; Local Variables: *** -;;; c-basic-offset:4 *** -;;; End: *** -*/ diff -r c21e7c12dd50 -r 674071846ee3 rt/Makefile --- a/rt/Makefile Thu Apr 20 13:19:36 2006 +0000 +++ b/rt/Makefile Thu Apr 20 13:31:31 2006 +0000 @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ # -# Makefile Echtzeitmodule +# Makefile # # $Id$ # @@ -9,7 +9,7 @@ ifneq ($(KERNELRELEASE),) #------------------------------------------------------------------------------ -# Kbuild-Abschnitt +# kbuild section #------------------------------------------------------------------------------ ifneq ($(wildcard $(src)/rt.conf),) @@ -44,7 +44,7 @@ else #------------------------------------------------------------------------------ -# Default-Abschnitt +# default section #------------------------------------------------------------------------------ ifneq ($(wildcard rt.conf),) diff -r c21e7c12dd50 -r 674071846ee3 rt/msrserv.pl --- a/rt/msrserv.pl Thu Apr 20 13:19:36 2006 +0000 +++ b/rt/msrserv.pl Thu Apr 20 13:31:31 2006 +0000 @@ -2,14 +2,6 @@ #------------------------------------------------------------ # # (C) Copyright -# Diese Software ist geistiges Eigentum der -# Ingenieurgemeinschaft IgH. Sie darf von -# Toyota Motorsport GmbH -# beliebig kopiert und veraendert werden. -# Die Weitergabe an Dritte ist untersagt. -# Dieser Urhebrrechtshinweis muss erhalten -# bleiben. -# # Ingenieurgemeinschaft IgH # Heinz-Baecker-Strasse 34 # D-45356 Essen @@ -20,13 +12,13 @@ # #------------------------------------------------------------ # -# Multithreaded Server +# Multithreaded Server # according to the example from "Programming Perl" -# this code is improved according to the example from -# perldoc perlipc, so now safely being usable under Perl 5.8 +# this code is improved according to the example from +# perldoc perlipc, so now safely being usable under Perl 5.8 # (see note (*)) # -# works with read/write on a device-file +# works with read/write on a device-file # # $Revision: 1.1 $ # $Date: 2004/10/01 16:00:42 $ @@ -40,9 +32,9 @@ use Socket; use Carp; use FileHandle; -use Getopt::Std; - -use Sys::Syslog qw(:DEFAULT setlogsock); +use Getopt::Std; + +use Sys::Syslog qw(:DEFAULT setlogsock); use vars qw ( $self $pid $dolog $port $dev %opts $selfbase @@ -53,25 +45,25 @@ # Do logging to local syslogd by unix-domain socket instead of inetd -setlogsock("unix"); +setlogsock("unix"); # Prototypes and some little Tools sub spawn; -sub logmsg { +sub logmsg { my ($level, $debug, @text) = @_; syslog("daemon|$level", @text) if $debug > $dolog; # print STDERR "daemon|$level", @text, "\n" if $dolog; } sub out { - my $waitpid = wait; + my $waitpid = wait; logmsg("notice", 2, "$waitpid exited"); unlink "$selfbase.pid"; exit 0; } sub help { - print "\n usage: $0 [-l og] [-h elp] [-p port] [-d device]\n"; - exit; + print "\n usage: $0 [-l og] [-h elp] [-p port] [-d device]\n"; + exit; } # Process Options @@ -81,7 +73,7 @@ "p" => 2345, "d" => "/dev/msr" ); - + getopts("lhp:d:", \%opts); help if $opts{"h"}; @@ -94,7 +86,7 @@ $dev = $opts{"d"}; $blksize = 1024; # try to write as much bytes $instdir = "/opt/msr"; -$authfile = "$instdir/etc/hosts.auth"; +$authfile = "$instdir/etc/hosts.auth"; # Start logging openlog($self, 'pid'); @@ -127,12 +119,12 @@ or die "setsocketopt: $!"; bind (Server, sockaddr_in($port, INADDR_ANY)) or die "bind: $!"; -listen (Server, SOMAXCONN) +listen (Server, SOMAXCONN) or die "listen: $!"; %authhosts = (); # get authorized hosts -open (AUTH, $authfile) +open (AUTH, $authfile) or logmsg ("notice", 2, "Could not read allowed hosts file: $authfile"); while () { chomp; @@ -176,26 +168,26 @@ my $name = lc gethostbyaddr($iaddr, AF_INET); my $ipaddr = inet_ntoa($iaddr); my $n = 0; - + # tell about the requesting client logmsg ("info", 2, "Connection from >$ipaddr< ($name) at port $port"); - + spawn sub { my ($head, $hlen, $pos, $pegel, $typ, $siz, $nch, $nrec, $dat, $i, $j, $n, $llen); my ($watchpegel, $shmpegel); my ($rin, $rout, $in, $line, $data_requested, $oversample); my (@channels); - + # to use stdio on writing to Client Client->autoflush(); - -# Open Device + +# Open Device sysopen (DEV, "$dev", O_RDWR | O_NONBLOCK, 0666) or die("can't open $dev"); - + # Bitmask to check for input on stdin $rin = ""; - vec($rin, fileno(Client), 1) = 1; - + vec($rin, fileno(Client), 1) = 1; + # check for authorized hosts my $access = 'deny'; $access = 'allow' if $authhosts{$ipaddr}; @@ -208,14 +200,14 @@ $len -= $written; $offset += $written; } - + while ( 1 ) { $in = select ($rout=$rin, undef, undef, 0.0); # poll client # look for any Input from Client if ($in) { # exit on EOF $len = sysread (Client, $line, $blksize) or exit; - logmsg("info", 0, "got $len bytes: \"$line\""); + logmsg("info", 0, "got $len bytes: \"$line\""); $offset = 0; # copy request to device while ($len) { @@ -239,11 +231,11 @@ sub spawn { my $coderef = shift; - + unless (@_ == 0 && $coderef && ref($coderef) eq 'CODE') { confess "usage: spawn CODEREF"; } - my $pid; + my $pid; if (!defined($pid = fork)) { logmsg ("notice", 2, "fork failed: $!"); return; @@ -258,15 +250,3 @@ # STDOUT->autoflush(); exit &$coderef(); } - - - - - - - - - - - -