Frame-Debugging ins Device ausgelagert und verbessert.
authorFlorian Pose <fp@igh-essen.com>
Fri, 24 Feb 2006 13:09:13 +0000
changeset 78 3d74183d6c6b
parent 77 677967864795
child 79 319a97c1f0f9
Frame-Debugging ins Device ausgelagert und verbessert.
include/EtherCAT_dev.h
master/device.c
master/device.h
master/frame.c
master/frame.h
master/module.c
--- a/include/EtherCAT_dev.h	Fri Feb 24 10:19:26 2006 +0000
+++ b/include/EtherCAT_dev.h	Fri Feb 24 13:09:13 2006 +0000
@@ -37,9 +37,9 @@
                                    struct module *);
 void EtherCAT_dev_unregister(unsigned int, ec_device_t *);
 
-int EtherCAT_dev_is_ec(ec_device_t *, struct net_device *);
+int EtherCAT_dev_is_ec(const ec_device_t *, const struct net_device *);
 void EtherCAT_dev_state(ec_device_t *, ec_device_state_t);
-void EtherCAT_dev_receive(ec_device_t *, void *, unsigned int);
+void EtherCAT_dev_receive(ec_device_t *, const void *, size_t);
 
 /*****************************************************************************/
 
--- a/master/device.c	Fri Feb 24 10:19:26 2006 +0000
+++ b/master/device.c	Fri Feb 24 13:09:13 2006 +0000
@@ -15,31 +15,30 @@
 #include <linux/delay.h>
 
 #include "device.h"
+#include "master.h"
 
 /*****************************************************************************/
 
 /**
    EtherCAT-Geräte-Konstuktor.
-
-   Initialisiert ein EtherCAT-Gerät, indem es die Variablen
-   in der Struktur auf die Default-Werte setzt.
-
-   @param ecd Zu initialisierendes EtherCAT-Gerät
-*/
-
-int ec_device_init(ec_device_t *ecd)
-{
-    ecd->dev = NULL;
-    ecd->open = 0;
-    ecd->tx_time = 0;
-    ecd->rx_time = 0;
-    ecd->state = EC_DEVICE_STATE_READY;
-    ecd->rx_data_length = 0;
-    ecd->isr = NULL;
-    ecd->module = NULL;
-    ecd->error_reported = 0;
-
-    if ((ecd->tx_skb = dev_alloc_skb(ETH_HLEN + EC_MAX_FRAME_SIZE)) == NULL) {
+*/
+
+int ec_device_init(ec_device_t *device, /**< EtherCAT-Gerät */
+                   ec_master_t *master /**< Zugehöriger Master */
+                   )
+{
+    device->master = master;
+    device->dev = NULL;
+    device->open = 0;
+    device->tx_time = 0;
+    device->rx_time = 0;
+    device->state = EC_DEVICE_STATE_READY;
+    device->rx_data_size = 0;
+    device->isr = NULL;
+    device->module = NULL;
+    device->error_reported = 0;
+
+    if ((device->tx_skb = dev_alloc_skb(ETH_HLEN + EC_MAX_FRAME_SIZE)) == NULL) {
         printk(KERN_ERR "EtherCAT: Error allocating device socket buffer!\n");
         return -1;
     }
@@ -54,19 +53,17 @@
 
    Gibt den dynamisch allozierten Speicher des
    EtherCAT-Gerätes (die beiden Socket-Buffer) wieder frei.
-
-   @param ecd EtherCAT-Gerät
-*/
-
-void ec_device_clear(ec_device_t *ecd)
-{
-    if (ecd->open) ec_device_close(ecd);
-
-    ecd->dev = NULL;
-
-    if (ecd->tx_skb) {
-        dev_kfree_skb(ecd->tx_skb);
-        ecd->tx_skb = NULL;
+*/
+
+void ec_device_clear(ec_device_t *device /**< EtherCAT-Gerät */)
+{
+    if (device->open) ec_device_close(device);
+
+    device->dev = NULL;
+
+    if (device->tx_skb) {
+        dev_kfree_skb(device->tx_skb);
+        device->tx_skb = NULL;
     }
 }
 
@@ -79,40 +76,38 @@
    auf das EtherCAT-Gerät auf Gültigkeit geprüft und der
    Gerätezustand zurückgesetzt.
 
-   @param ecd EtherCAT-Gerät
-
-   @return 0 bei Erfolg, < 0: Ungültiger Zeiger, oder open()
-   fehlgeschlagen
-*/
-
-int ec_device_open(ec_device_t *ecd)
+   \return 0 bei Erfolg, < 0: Ungültiger Zeiger, oder open()
+           fehlgeschlagen
+*/
+
+int ec_device_open(ec_device_t *device /**< EtherCAT-Gerät */)
 {
     unsigned int i;
 
-    if (!ecd) {
+    if (!device) {
         printk(KERN_ERR "EtherCAT: Trying to open a NULL device!\n");
         return -1;
     }
 
-    if (!ecd->dev) {
+    if (!device->dev) {
         printk(KERN_ERR "EtherCAT: No net_device to open!\n");
         return -1;
     }
 
-    if (ecd->open) {
+    if (device->open) {
         printk(KERN_WARNING "EtherCAT: Device already opened!\n");
     }
     else {
         // Device could have received frames before
-        for (i = 0; i < 4; i++) ec_device_call_isr(ecd);
+        for (i = 0; i < 4; i++) ec_device_call_isr(device);
 
         // Reset old device state
-        ecd->state = EC_DEVICE_STATE_READY;
-
-        if (ecd->dev->open(ecd->dev) == 0) ecd->open = 1;
-    }
-
-    return ecd->open ? 0 : -1;
+        device->state = EC_DEVICE_STATE_READY;
+
+        if (device->dev->open(device->dev) == 0) device->open = 1;
+    }
+
+    return device->open ? 0 : -1;
 }
 
 /*****************************************************************************/
@@ -120,27 +115,25 @@
 /**
    Führt die stop()-Funktion des net_devices aus.
 
-   @param ecd EtherCAT-Gerät
-
-   @return 0 bei Erfolg, < 0: Kein Gerät zum Schliessen oder
+   \return 0 bei Erfolg, < 0: Kein Gerät zum Schliessen oder
    Schliessen fehlgeschlagen.
 */
 
-int ec_device_close(ec_device_t *ecd)
-{
-    if (!ecd->dev) {
+int ec_device_close(ec_device_t *device /**< EtherCAT-Gerät */)
+{
+    if (!device->dev) {
         printk(KERN_ERR "EtherCAT: No device to close!\n");
         return -1;
     }
 
-    if (!ecd->open) {
+    if (!device->open) {
         printk(KERN_WARNING "EtherCAT: Device already closed!\n");
     }
     else {
-        if (ecd->dev->stop(ecd->dev) == 0) ecd->open = 0;
-    }
-
-    return !ecd->open ? 0 : -1;
+        if (device->dev->stop(device->dev) == 0) device->open = 0;
+    }
+
+    return !device->open ? 0 : -1;
 }
 
 /*****************************************************************************/
@@ -151,14 +144,14 @@
    \return Zeiger auf den Speicher, in den die Frame-Daten sollen.
 */
 
-uint8_t *ec_device_prepare(ec_device_t *ecd /**< EtherCAT-Gerät */)
+uint8_t *ec_device_prepare(ec_device_t *device /**< EtherCAT-Gerät */)
 {
     // Clear transmit socket buffer and reserve space for Ethernet-II header
-    skb_trim(ecd->tx_skb, 0);
-    skb_reserve(ecd->tx_skb, ETH_HLEN);
+    skb_trim(device->tx_skb, 0);
+    skb_reserve(device->tx_skb, ETH_HLEN);
 
     // Erstmal Speicher für maximal langen Frame reservieren
-    return skb_put(ecd->tx_skb, EC_MAX_FRAME_SIZE);
+    return skb_put(device->tx_skb, EC_MAX_FRAME_SIZE);
 }
 
 /*****************************************************************************/
@@ -174,27 +167,32 @@
    nicht empfangen, oder kein Speicher mehr vorhanden
 */
 
-void ec_device_send(ec_device_t *ecd, /**< EtherCAT-Gerät */
+void ec_device_send(ec_device_t *device, /**< EtherCAT-Gerät */
                     unsigned int length /**< Länge der zu sendenden Daten */
                     )
 {
     struct ethhdr *eth;
 
     // Framegroesse auf (jetzt bekannte) Laenge abschneiden
-    skb_trim(ecd->tx_skb, length);
+    skb_trim(device->tx_skb, length);
 
     // Ethernet-II-Header hinzufuegen
-    eth = (struct ethhdr *) skb_push(ecd->tx_skb, ETH_HLEN);
+    eth = (struct ethhdr *) skb_push(device->tx_skb, ETH_HLEN);
     eth->h_proto = htons(0x88A4);
-    memcpy(eth->h_source, ecd->dev->dev_addr, ecd->dev->addr_len);
-    memset(eth->h_dest, 0xFF, ecd->dev->addr_len);
-
-    ecd->state = EC_DEVICE_STATE_SENT;
-    ecd->rx_data_length = 0;
+    memcpy(eth->h_source, device->dev->dev_addr, device->dev->addr_len);
+    memset(eth->h_dest, 0xFF, device->dev->addr_len);
+
+    device->state = EC_DEVICE_STATE_SENT;
+    device->rx_data_size = 0;
+
+    if (unlikely(device->master->debug_level > 1)) {
+        printk(KERN_DEBUG "EtherCAT: Sending frame:\n");
+        ec_data_print(device->tx_skb->data + ETH_HLEN, device->tx_skb->len);
+    }
 
     // Senden einleiten
-    rdtscl(ecd->tx_time); // Get CPU cycles
-    ecd->dev->hard_start_xmit(ecd->tx_skb, ecd->dev);
+    rdtscl(device->tx_time); // Get CPU cycles
+    device->dev->hard_start_xmit(device->tx_skb, device->dev);
 }
 
 /*****************************************************************************/
@@ -205,9 +203,9 @@
    \return Empfangene Bytes, oder 0, wenn kein Frame empfangen wurde.
 */
 
-unsigned int ec_device_received(const ec_device_t *ecd)
-{
-    return ecd->rx_data_length;
+unsigned int ec_device_received(const ec_device_t *device)
+{
+    return device->rx_data_size;
 }
 
 /*****************************************************************************/
@@ -218,54 +216,48 @@
    \return Adresse auf empfangene Daten.
 */
 
-uint8_t *ec_device_data(ec_device_t *ecd)
-{
-    return ecd->rx_data;
+uint8_t *ec_device_data(ec_device_t *device)
+{
+    return device->rx_data;
 }
 
 /*****************************************************************************/
 
 /**
    Ruft die Interrupt-Routine der Netzwerkkarte auf.
-
-   @param ecd EtherCAT-Gerät
-
-   @return Anzahl der kopierten Bytes bei Erfolg, sonst < 0
-*/
-
-void ec_device_call_isr(ec_device_t *ecd)
-{
-    if (likely(ecd->isr)) ecd->isr(0, ecd->dev, NULL);
+*/
+
+void ec_device_call_isr(ec_device_t *device /**< EtherCAT-Gerät */)
+{
+    if (likely(device->isr)) device->isr(0, device->dev, NULL);
 }
 
 /*****************************************************************************/
 
 /**
    Gibt alle Informationen über das Device-Objekt aus.
-
-   @param ecd EtherCAT-Gerät
-*/
-
-void ec_device_print(ec_device_t *ecd)
+*/
+
+void ec_device_print(ec_device_t *device /**< EtherCAT-Gerät */)
 {
     printk(KERN_DEBUG "---EtherCAT device information begin---\n");
 
-    if (ecd)
+    if (device)
     {
         printk(KERN_DEBUG "Assigned net_device: %X\n",
-               (unsigned) ecd->dev);
+               (unsigned) device->dev);
         printk(KERN_DEBUG "Transmit socket buffer: %X\n",
-               (unsigned) ecd->tx_skb);
+               (unsigned) device->tx_skb);
         printk(KERN_DEBUG "Time of last transmission: %u\n",
-               (unsigned) ecd->tx_time);
+               (unsigned) device->tx_time);
         printk(KERN_DEBUG "Time of last receive: %u\n",
-               (unsigned) ecd->rx_time);
+               (unsigned) device->rx_time);
         printk(KERN_DEBUG "Actual device state: %i\n",
-               (int) ecd->state);
+               (int) device->state);
         printk(KERN_DEBUG "Receive buffer: %X\n",
-               (unsigned) ecd->rx_data);
+               (unsigned) device->rx_data);
         printk(KERN_DEBUG "Receive buffer fill state: %u/%u\n",
-               (unsigned) ecd->rx_data_length, EC_MAX_FRAME_SIZE);
+               (unsigned) device->rx_data_size, EC_MAX_FRAME_SIZE);
     }
     else
     {
@@ -275,32 +267,108 @@
     printk(KERN_DEBUG "---EtherCAT device information end---\n");
 }
 
+/*****************************************************************************/
+
+/**
+   Gibt das letzte Rahmenpaar aus.
+*/
+
+void ec_device_debug(const ec_device_t *device /**< EtherCAT-Gerät */)
+{
+    printk(KERN_DEBUG "EtherCAT: >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
+    ec_data_print(device->tx_skb->data + ETH_HLEN, device->tx_skb->len);
+    printk(KERN_DEBUG "------------------------------------------------\n");
+    ec_data_print_diff(device->tx_skb->data + ETH_HLEN, device->rx_data,
+                       device->rx_data_size);
+    printk(KERN_DEBUG "EtherCAT: <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
+}
+
+/*****************************************************************************/
+
+/**
+   Gibt Frame-Inhalte zwecks Debugging aus.
+*/
+
+void ec_data_print(const uint8_t *data /**< Daten */,
+                   size_t size /**< Anzahl Bytes */
+                   )
+{
+    size_t i;
+
+    printk(KERN_DEBUG);
+    for (i = 0; i < size; i++) {
+        printk("%02X ", data[i]);
+        if ((i + 1) % 16 == 0) printk("\n" KERN_DEBUG);
+    }
+    printk("\n");
+}
+
+/*****************************************************************************/
+
+/**
+   Gibt Frame-Inhalte zwecks Debugging aus, differentiell.
+*/
+
+void ec_data_print_diff(const uint8_t *d1, /**< Daten 1 */
+                        const uint8_t *d2, /**< Daten 2 */
+                        size_t size /** Anzahl Bytes */
+                        )
+{
+    size_t i;
+
+    printk(KERN_DEBUG);
+    for (i = 0; i < size; i++) {
+        if (d1[i] == d2[i]) printk(".. ");
+        else printk("%02X ", d2[i]);
+        if ((i + 1) % 16 == 0) printk("\n" KERN_DEBUG);
+    }
+    printk("\n");
+}
+
 /******************************************************************************
  *
  * Treiberschnittstelle
  *
  *****************************************************************************/
 
-void EtherCAT_dev_state(ec_device_t *ecd, ec_device_state_t state)
-{
-    ecd->state = state;
-}
-
-/*****************************************************************************/
-
-int EtherCAT_dev_is_ec(ec_device_t *ecd, struct net_device *dev)
-{
-    return ecd && ecd->dev == dev;
-}
-
-/*****************************************************************************/
-
-void EtherCAT_dev_receive(ec_device_t *ecd, void *data, unsigned int size)
+/**
+   Setzt den Zustand des EtherCAT-Gerätes.
+*/
+
+void EtherCAT_dev_state(ec_device_t *device,  /**< EtherCAT-Gerät */
+                        ec_device_state_t state /**< Neuer Zustand */
+                        )
+{
+    device->state = state;
+}
+
+/*****************************************************************************/
+
+/**
+   Prüft, ob das Net-Device \a dev zum registrierten EtherCAT-Gerät gehört.
+*/
+
+int EtherCAT_dev_is_ec(const ec_device_t *device,  /**< EtherCAT-Gerät */
+                       const struct net_device *dev /**< Net-Device */
+                       )
+{
+    return device && device->dev == dev;
+}
+
+/*****************************************************************************/
+
+void EtherCAT_dev_receive(ec_device_t *device, const void *data, size_t size)
 {
     // Copy received data to ethercat-device buffer
-    memcpy(ecd->rx_data, data, size);
-    ecd->rx_data_length = size;
-    ecd->state = EC_DEVICE_STATE_RECEIVED;
+    memcpy(device->rx_data, data, size);
+    device->rx_data_size = size;
+    device->state = EC_DEVICE_STATE_RECEIVED;
+
+    if (unlikely(device->master->debug_level > 1)) {
+        printk(KERN_DEBUG "EtherCAT: Received frame:\n");
+        ec_data_print_diff(device->tx_skb->data + ETH_HLEN, device->rx_data,
+                           device->rx_data_size);
+    }
 }
 
 /*****************************************************************************/
--- a/master/device.h	Fri Feb 24 10:19:26 2006 +0000
+++ b/master/device.h	Fri Feb 24 13:09:13 2006 +0000
@@ -13,8 +13,9 @@
 
 #include <linux/interrupt.h>
 
+#include "../include/EtherCAT_rt.h"
+#include "../include/EtherCAT_dev.h"
 #include "globals.h"
-#include "../include/EtherCAT_dev.h"
 
 /*****************************************************************************/
 
@@ -28,33 +29,40 @@
 
 struct ec_device
 {
+    ec_master_t *master; /**< EtherCAT-Master */
     struct net_device *dev; /**< Zeiger auf das reservierte net_device */
-    unsigned int open;      /**< Das net_device ist geoeffnet. */
+    uint8_t open; /**< Das net_device ist geoeffnet. */
     struct sk_buff *tx_skb; /**< Zeiger auf Transmit-Socketbuffer */
     unsigned long tx_time;  /**< Zeit des letzten Sendens */
     unsigned long rx_time;  /**< Zeit des letzten Empfangs */
-    volatile ec_device_state_t state; /**< Zustand des Gerätes */
+    ec_device_state_t state; /**< Zustand des Gerätes */
     uint8_t rx_data[EC_MAX_FRAME_SIZE]; /**< Speicher für empfangene Rahmen */
-    volatile unsigned int rx_data_length; /**< Länge des empfangenen Rahmens */
+    size_t rx_data_size; /**< Länge des empfangenen Rahmens */
     irqreturn_t (*isr)(int, void *, struct pt_regs *); /**< Adresse der ISR */
     struct module *module; /**< Zeiger auf das Modul, das das Gerät zur
                               Verfügung stellt. */
-    int error_reported; /**< Zeigt an, ob ein Fehler im zyklischen Code
-                           bereits gemeldet wurde. */
+    uint8_t error_reported; /**< Zeigt an, ob ein Fehler im zyklischen Code
+                               bereits gemeldet wurde. */
 };
 
 /*****************************************************************************/
 
-int ec_device_init(ec_device_t *);
+int ec_device_init(ec_device_t *, ec_master_t *);
 void ec_device_clear(ec_device_t *);
+
 int ec_device_open(ec_device_t *);
 int ec_device_close(ec_device_t *);
+
 void ec_device_call_isr(ec_device_t *);
 uint8_t *ec_device_prepare(ec_device_t *);
-void ec_device_send(ec_device_t *, unsigned int);
+void ec_device_send(ec_device_t *, size_t);
 unsigned int ec_device_received(const ec_device_t *);
 uint8_t *ec_device_data(ec_device_t *);
 
+void ec_device_debug(const ec_device_t *);
+void ec_data_print(const uint8_t *, size_t);
+void ec_data_print_diff(const uint8_t *, const uint8_t *, size_t);
+
 /*****************************************************************************/
 
 #endif
--- a/master/frame.c	Fri Feb 24 10:19:26 2006 +0000
+++ b/master/frame.c	Fri Feb 24 13:09:13 2006 +0000
@@ -351,7 +351,7 @@
     if (unlikely(received_length < EC_FRAME_HEADER_SIZE)) {
         printk(KERN_ERR "EtherCAT: Received frame with incomplete EtherCAT"
                " frame header!\n");
-        ec_frame_print(frame);
+        ec_device_debug(device);
         return -1;
     }
 
@@ -364,7 +364,7 @@
     if (unlikely(frame_length > received_length)) {
         printk(KERN_ERR "EtherCAT: Received corrupted frame (length does"
                " not match)!\n");
-        ec_frame_print(frame);
+        ec_device_debug(device);
         return -1;
     }
 
@@ -378,7 +378,7 @@
                  + data_length + EC_COMMAND_FOOTER_SIZE > received_length)) {
         printk(KERN_ERR "EtherCAT: Received frame with incomplete command"
                " data!\n");
-        ec_frame_print(frame);
+        ec_device_debug(device);
         return -1;
     }
 
@@ -387,7 +387,7 @@
                  || frame->data_length != data_length))
     {
         printk(KERN_WARNING "EtherCAT: WARNING - Send/Receive anomaly!\n");
-        ec_frame_print(frame); // FIXME uninteressant...
+        ec_device_debug(device);
         ec_device_call_isr(device); // Empfangenes "vergessen"
         return -1;
     }
@@ -401,10 +401,6 @@
     // Working-Counter setzen
     frame->working_counter = EC_READ_U16(data);
 
-    if (unlikely(frame->master->debug_level > 1)) {
-        ec_frame_print(frame);
-    }
-
     return 0;
 }
 
@@ -452,28 +448,6 @@
 
 /*****************************************************************************/
 
-/**
-   Gibt Frame-Inhalte zwecks Debugging aus.
-*/
-
-void ec_frame_print(const ec_frame_t *frame /**< EtherCAT-Frame */)
-{
-    unsigned int i;
-
-    printk(KERN_DEBUG "EtherCAT: Frame contents (%i Bytes):\n",
-           frame->data_length);
-
-    printk(KERN_DEBUG);
-    for (i = 0; i < frame->data_length; i++)
-    {
-        printk("%02X ", frame->data[i]);
-        if ((i + 1) % 16 == 0) printk("\n" KERN_DEBUG);
-    }
-    printk("\n");
-}
-
-/*****************************************************************************/
-
 /* Emacs-Konfiguration
 ;;; Local Variables: ***
 ;;; c-basic-offset:4 ***
--- a/master/frame.h	Fri Feb 24 10:19:26 2006 +0000
+++ b/master/frame.h	Fri Feb 24 13:09:13 2006 +0000
@@ -118,8 +118,6 @@
 int ec_frame_receive(ec_frame_t *);
 int ec_frame_send_receive(ec_frame_t *);
 
-void ec_frame_print(const ec_frame_t *);
-
 /*****************************************************************************/
 
 #endif
--- a/master/module.c	Fri Feb 24 10:19:26 2006 +0000
+++ b/master/module.c	Fri Feb 24 13:09:13 2006 +0000
@@ -186,7 +186,7 @@
 
     ecd = &master->device;
 
-    if (ec_device_init(ecd) < 0) return NULL;
+    if (ec_device_init(ecd, master) < 0) return NULL;
 
     ecd->dev = dev;
     ecd->tx_skb->dev = dev;