From 300421cd6ee812775a763a58249fd55ad05c93f2 Mon Sep 17 00:00:00 2001 From: Florian Pose <fp@igh-essen.com> Date: Fri, 24 Feb 2006 13:09:13 +0000 Subject: [PATCH] Frame-Debugging ins Device ausgelagert und verbessert. --- include/EtherCAT_dev.h | 4 +- master/device.c | 242 ++++++++++++++++++++++++++--------------- master/device.h | 24 ++-- master/frame.c | 34 +----- master/frame.h | 2 - master/module.c | 2 +- 6 files changed, 178 insertions(+), 130 deletions(-) diff --git a/include/EtherCAT_dev.h b/include/EtherCAT_dev.h index 73aa2b20..7f397242 100644 --- a/include/EtherCAT_dev.h +++ b/include/EtherCAT_dev.h @@ -37,9 +37,9 @@ ec_device_t *EtherCAT_dev_register(unsigned int, struct net_device *, 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); /*****************************************************************************/ diff --git a/master/device.c b/master/device.c index 5815f45a..a71061a4 100644 --- a/master/device.c +++ b/master/device.c @@ -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) +int ec_device_init(ec_device_t *device, /**< EtherCAT-Gerät */ + ec_master_t *master /**< Zugehöriger Master */ + ) { - 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) { + 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 @@ int ec_device_init(ec_device_t *ecd) 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) +void ec_device_clear(ec_device_t *device /**< EtherCAT-Gerät */) { - if (ecd->open) ec_device_close(ecd); + if (device->open) ec_device_close(device); - ecd->dev = NULL; + device->dev = NULL; - if (ecd->tx_skb) { - dev_kfree_skb(ecd->tx_skb); - ecd->tx_skb = NULL; + if (device->tx_skb) { + dev_kfree_skb(device->tx_skb); + device->tx_skb = NULL; } } @@ -79,40 +76,38 @@ void ec_device_clear(ec_device_t *ecd) 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 + \return 0 bei Erfolg, < 0: Ungültiger Zeiger, oder open() + fehlgeschlagen */ -int ec_device_open(ec_device_t *ecd) +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; + device->state = EC_DEVICE_STATE_READY; - if (ecd->dev->open(ecd->dev) == 0) ecd->open = 1; + if (device->dev->open(device->dev) == 0) device->open = 1; } - return ecd->open ? 0 : -1; + return device->open ? 0 : -1; } /*****************************************************************************/ @@ -120,27 +115,25 @@ int ec_device_open(ec_device_t *ecd) /** 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) +int ec_device_close(ec_device_t *device /**< EtherCAT-Gerät */) { - if (!ecd->dev) { + 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; + if (device->dev->stop(device->dev) == 0) device->open = 0; } - return !ecd->open ? 0 : -1; + return !device->open ? 0 : -1; } /*****************************************************************************/ @@ -151,14 +144,14 @@ int ec_device_close(ec_device_t *ecd) \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 @@ uint8_t *ec_device_prepare(ec_device_t *ecd /**< EtherCAT-Ger 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); + 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; - ecd->state = EC_DEVICE_STATE_SENT; - ecd->rx_data_length = 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 @@ void ec_device_send(ec_device_t *ecd, /**< EtherCAT-Ger \return Empfangene Bytes, oder 0, wenn kein Frame empfangen wurde. */ -unsigned int ec_device_received(const ec_device_t *ecd) +unsigned int ec_device_received(const ec_device_t *device) { - return ecd->rx_data_length; + return device->rx_data_size; } /*****************************************************************************/ @@ -218,54 +216,48 @@ unsigned int ec_device_received(const ec_device_t *ecd) \return Adresse auf empfangene Daten. */ -uint8_t *ec_device_data(ec_device_t *ecd) +uint8_t *ec_device_data(ec_device_t *device) { - return ecd->rx_data; + 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) +void ec_device_call_isr(ec_device_t *device /**< EtherCAT-Gerät */) { - if (likely(ecd->isr)) ecd->isr(0, ecd->dev, NULL); + 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 @@ void ec_device_print(ec_device_t *ecd) 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) +/** + 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 */ + ) { - ecd->state = state; + device->state = state; } /*****************************************************************************/ -int EtherCAT_dev_is_ec(ec_device_t *ecd, struct net_device *dev) +/** + 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 ecd && ecd->dev == dev; + return device && device->dev == dev; } /*****************************************************************************/ -void EtherCAT_dev_receive(ec_device_t *ecd, void *data, unsigned int size) +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); + } } /*****************************************************************************/ diff --git a/master/device.h b/master/device.h index f11bcd31..26bade5d 100644 --- a/master/device.h +++ b/master/device.h @@ -13,8 +13,9 @@ #include <linux/interrupt.h> -#include "globals.h" +#include "../include/EtherCAT_rt.h" #include "../include/EtherCAT_dev.h" +#include "globals.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 diff --git a/master/frame.c b/master/frame.c index d3146c31..e2e30a65 100644 --- a/master/frame.c +++ b/master/frame.c @@ -351,7 +351,7 @@ int ec_frame_receive(ec_frame_t *frame /**< Gesendeter Rahmen */) 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 @@ int ec_frame_receive(ec_frame_t *frame /**< Gesendeter Rahmen */) 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 @@ int ec_frame_receive(ec_frame_t *frame /**< Gesendeter Rahmen */) + 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 @@ int ec_frame_receive(ec_frame_t *frame /**< Gesendeter Rahmen */) || 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 @@ int ec_frame_receive(ec_frame_t *frame /**< Gesendeter Rahmen */) // 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 @@ int ec_frame_send_receive(ec_frame_t *frame /*****************************************************************************/ -/** - 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 *** diff --git a/master/frame.h b/master/frame.h index c0698d6f..165c5e62 100644 --- a/master/frame.h +++ b/master/frame.h @@ -118,8 +118,6 @@ int ec_frame_send(ec_frame_t *); int ec_frame_receive(ec_frame_t *); int ec_frame_send_receive(ec_frame_t *); -void ec_frame_print(const ec_frame_t *); - /*****************************************************************************/ #endif diff --git a/master/module.c b/master/module.c index 05dd1481..cac451aa 100644 --- a/master/module.c +++ b/master/module.c @@ -186,7 +186,7 @@ ec_device_t *EtherCAT_dev_register(unsigned int master_index, 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; -- GitLab