# HG changeset patch # User Florian Pose # Date 1186671674 0 # Node ID fe7cf37c33f1ed9f34ee819da358d5d5c0f7d56f # Parent 77b79a29e0e7d104008ca8331e4d03428015510f Implemented debug frame ring to output the last n frames for debugging reasons. diff -r 77b79a29e0e7 -r fe7cf37c33f1 configure.ac --- a/configure.ac Thu Aug 09 14:47:37 2007 +0000 +++ b/configure.ac Thu Aug 09 15:01:14 2007 +0000 @@ -368,6 +368,30 @@ AM_CONDITIONAL(ENABLE_DEBUG_IF, test "x$dbg" = "x1") #------------------------------------------------------------------------------ +# Debug ring +#------------------------------------------------------------------------------ + +AC_ARG_ENABLE([debug-ring], + AS_HELP_STRING([--enable-debug-ring], + [Create a debug ring to record frames @<:@NO@:>@]), + [ + case "${enableval}" in + yes) debugring=1 + ;; + no) debugring=0 + ;; + *) AC_MSG_ERROR([Invalid value for --enable-debug-ring]) + ;; + esac + ], + [debugring=0] +) + +if test "x${debugring}" = "x1"; then + AC_DEFINE([EC_DEBUG_RING], [1], [Debug ring enabled]) +fi + +#------------------------------------------------------------------------------ # Dummy master module #------------------------------------------------------------------------------ diff -r 77b79a29e0e7 -r fe7cf37c33f1 master/device.c --- a/master/device.c Thu Aug 09 14:47:37 2007 +0000 +++ b/master/device.c Thu Aug 09 15:01:14 2007 +0000 @@ -46,6 +46,18 @@ #include "device.h" #include "master.h" +#ifdef EC_DEBUG_RING +#define timersub(a, b, result) \ + do { \ + (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ + (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ + if ((result)->tv_usec < 0) { \ + --(result)->tv_sec; \ + (result)->tv_usec += 1000000; \ + } \ + } while (0) +#endif + /*****************************************************************************/ /** @@ -61,6 +73,10 @@ char ifname[10]; char mb = 'x'; #endif +#ifdef EC_DEBUG_RING + device->debug_frame_index = 0; + device->debug_frame_count = 0; +#endif device->master = master; @@ -249,6 +265,10 @@ #ifdef EC_DEBUG_IF ec_debug_send(&device->dbg, device->tx_skb->data, ETH_HLEN + size); #endif +#ifdef EC_DEBUG_RING + ec_device_debug_ring_append( + device, TX, device->tx_skb->data + ETH_HLEN, size); +#endif // start sending device->dev->hard_start_xmit(device->tx_skb, device->dev); @@ -257,6 +277,79 @@ /*****************************************************************************/ +#ifdef EC_DEBUG_RING +/** + * Appends frame data to the debug ring. + */ + +void ec_device_debug_ring_append( + ec_device_t *device, /**< EtherCAT device */ + ec_debug_frame_dir_t dir, /**< direction */ + const void *data, /**< frame data */ + size_t size /**< data size */ + ) +{ + ec_debug_frame_t *df = &device->debug_frames[device->debug_frame_index]; + + df->dir = dir; + if (dir == TX) + do_gettimeofday(&df->t); + else + df->t = device->timeval_poll; + memcpy(df->data, data, size); + df->data_size = size; + + device->debug_frame_index++; + device->debug_frame_index %= EC_DEBUG_RING_SIZE; + if (unlikely(device->debug_frame_count < EC_DEBUG_RING_SIZE)) + device->debug_frame_count++; +} + +/*****************************************************************************/ + +/** + * Outputs the debug ring. + */ + +void ec_device_debug_ring_print( + const ec_device_t *device /**< EtherCAT device */ + ) +{ + int i; + unsigned int ring_index; + const ec_debug_frame_t *df; + struct timeval t0, diff; + + // calculate index of the newest frame in the ring to get its time + ring_index = (device->debug_frame_index + EC_DEBUG_RING_SIZE - 1) + % EC_DEBUG_RING_SIZE; + t0 = device->debug_frames[ring_index].t; + + EC_DBG("Debug ring %i:\n", ring_index); + + // calculate index of the oldest frame in the ring + ring_index = (device->debug_frame_index + EC_DEBUG_RING_SIZE + - device->debug_frame_count) % EC_DEBUG_RING_SIZE; + + for (i = 0; i < device->debug_frame_count; i++) { + df = &device->debug_frames[ring_index]; + timersub(&t0, &df->t, &diff); + + EC_DBG("Frame %i, dt=%u.%06u s, %s:\n", + i + 1 - device->debug_frame_count, + (unsigned int) diff.tv_sec, + (unsigned int) diff.tv_usec, + (df->dir == TX) ? "TX" : "RX"); + ec_print_data(df->data, df->data_size); + + ring_index++; + ring_index %= EC_DEBUG_RING_SIZE; + } +} +#endif + +/*****************************************************************************/ + /** Calls the poll function of the assigned net_device. The master itself works without using interrupts. Therefore the processing @@ -268,6 +361,9 @@ { device->cycles_poll = get_cycles(); device->jiffies_poll = jiffies; +#ifdef EC_DEBUG_RING + do_gettimeofday(&device->timeval_poll); +#endif device->poll(device->dev); } @@ -287,21 +383,23 @@ size_t size /**< number of bytes received */ ) { + const void *ec_data = data + ETH_HLEN; + size_t ec_size = size - ETH_HLEN; device->rx_count++; if (unlikely(device->master->debug_level > 1)) { EC_DBG("Received frame:\n"); - ec_print_data_diff(device->tx_skb->data + ETH_HLEN, - data + ETH_HLEN, size - ETH_HLEN); + ec_print_data_diff(device->tx_skb->data + ETH_HLEN, ec_data, ec_size); } #ifdef EC_DEBUG_IF ec_debug_send(&device->dbg, data, size); #endif - - ec_master_receive_datagrams(device->master, - data + ETH_HLEN, - size - ETH_HLEN); +#ifdef EC_DEBUG_RING + ec_device_debug_ring_append(device, RX, ec_data, ec_size); +#endif + + ec_master_receive_datagrams(device->master, ec_data, ec_size); } /*****************************************************************************/ diff -r 77b79a29e0e7 -r fe7cf37c33f1 master/device.h --- a/master/device.h Thu Aug 09 14:47:37 2007 +0000 +++ b/master/device.h Thu Aug 09 15:01:14 2007 +0000 @@ -51,6 +51,23 @@ #include "debug.h" #endif +#ifdef EC_DEBUG_RING +#define EC_DEBUG_RING_SIZE 10 + +typedef enum { + TX, RX +} ec_debug_frame_dir_t; + +typedef struct { + ec_debug_frame_dir_t dir; + struct timeval t; + unsigned int addr; + uint8_t data[EC_MAX_DATA_SIZE]; + unsigned int data_size; +} ec_debug_frame_t; + +#endif + /*****************************************************************************/ /** @@ -70,12 +87,20 @@ struct sk_buff *tx_skb; /**< transmit socket buffer */ struct ethhdr *eth; /**< pointer to ethernet header in socket buffer */ cycles_t cycles_poll; /**< cycles of last poll */ +#ifdef EC_DEBUG_RING + struct timeval timeval_poll; +#endif unsigned long jiffies_poll; /**< jiffies of last poll */ unsigned int tx_count; /**< number of frames sent */ unsigned int rx_count; /**< number of frames received */ #ifdef EC_DEBUG_IF ec_debug_t dbg; /**< debug device */ #endif +#ifdef EC_DEBUG_RING + ec_debug_frame_t debug_frames[EC_DEBUG_RING_SIZE]; + unsigned int debug_frame_index; + unsigned int debug_frame_count; +#endif }; /*****************************************************************************/ @@ -94,6 +119,12 @@ uint8_t *ec_device_tx_data(ec_device_t *); void ec_device_send(ec_device_t *, size_t); +#ifdef EC_DEBUG_RING +void ec_device_debug_ring_append(ec_device_t *, ec_debug_frame_dir_t, + const void *, size_t); +void ec_device_debug_ring_print(const ec_device_t *); +#endif + /*****************************************************************************/ #endif diff -r 77b79a29e0e7 -r fe7cf37c33f1 master/master.c --- a/master/master.c Thu Aug 09 14:47:37 2007 +0000 +++ b/master/master.c Thu Aug 09 15:01:14 2007 +0000 @@ -724,6 +724,9 @@ ec_print_data(cur_data - EC_DATAGRAM_HEADER_SIZE, EC_DATAGRAM_HEADER_SIZE + data_size + EC_DATAGRAM_FOOTER_SIZE); +#ifdef EC_DEBUG_RING + ec_device_debug_ring_print(&master->main_device); +#endif } cur_data += data_size + EC_DATAGRAM_FOOTER_SIZE;