Implemented debug frame ring to output the last n frames for debugging
reasons.
This commit is contained in:
parent
f76d31ec92
commit
68e6dfc108
24
configure.ac
24
configure.ac
|
|
@ -367,6 +367,30 @@ if test "x${dbg}" = "x1"; then
|
|||
fi
|
||||
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
|
||||
#------------------------------------------------------------------------------
|
||||
|
|
|
|||
108
master/device.c
108
master/device.c
|
|
@ -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 @@ int ec_device_init(ec_device_t *device, /**< EtherCAT device */
|
|||
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 @@ void ec_device_send(ec_device_t *device, /**< EtherCAT device */
|
|||
#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 @@ void ec_device_send(ec_device_t *device, /**< EtherCAT device */
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
#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 @@ void ec_device_poll(ec_device_t *device /**< EtherCAT device */)
|
|||
{
|
||||
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 @@ void ecdev_receive(ec_device_t *device, /**< EtherCAT device */
|
|||
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
|
||||
#ifdef EC_DEBUG_RING
|
||||
ec_device_debug_ring_append(device, RX, ec_data, ec_size);
|
||||
#endif
|
||||
|
||||
ec_master_receive_datagrams(device->master,
|
||||
data + ETH_HLEN,
|
||||
size - ETH_HLEN);
|
||||
ec_master_receive_datagrams(device->master, ec_data, ec_size);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -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 ec_device
|
|||
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 @@ void ec_device_poll(ec_device_t *);
|
|||
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
|
||||
|
|
|
|||
|
|
@ -724,6 +724,9 @@ void ec_master_receive_datagrams(ec_master_t *master, /**< EtherCAT master */
|
|||
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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue