# HG changeset patch # User Florian Pose # Date 1320846813 -3600 # Node ID 69f2b27023362648c3d771d5c079dad043235682 # Parent 8fa0571f9996e24734fd3899c7fce521400a2313 Adjusted frame statistics for the use with two devices. diff -r 8fa0571f9996 -r 69f2b2702336 master/cdev.c --- a/master/cdev.c Wed Nov 09 12:58:09 2011 +0100 +++ b/master/cdev.c Wed Nov 09 14:53:33 2011 +0100 @@ -213,13 +213,17 @@ data.devices[0].tx_count = master->main_device.tx_count; data.devices[0].rx_count = master->main_device.rx_count; data.devices[0].tx_bytes = master->main_device.tx_bytes; + data.devices[0].rx_bytes = master->main_device.rx_bytes; data.devices[0].tx_errors = master->main_device.tx_errors; for (i = 0; i < EC_RATE_COUNT; i++) { data.devices[0].tx_frame_rates[i] = master->main_device.tx_frame_rates[i]; + data.devices[0].rx_frame_rates[i] = + master->main_device.rx_frame_rates[i]; data.devices[0].tx_byte_rates[i] = master->main_device.tx_byte_rates[i]; - data.devices[0].loss_rates[i] = master->main_device.loss_rates[i]; + data.devices[0].rx_byte_rates[i] = + master->main_device.rx_byte_rates[i]; } if (master->backup_device.dev) { @@ -233,13 +237,34 @@ data.devices[1].tx_count = master->backup_device.tx_count; data.devices[1].rx_count = master->backup_device.rx_count; data.devices[1].tx_bytes = master->backup_device.tx_bytes; + data.devices[1].rx_bytes = master->backup_device.rx_bytes; data.devices[1].tx_errors = master->backup_device.tx_errors; for (i = 0; i < EC_RATE_COUNT; i++) { data.devices[1].tx_frame_rates[i] = master->backup_device.tx_frame_rates[i]; + data.devices[1].rx_frame_rates[i] = + master->backup_device.rx_frame_rates[i]; data.devices[1].tx_byte_rates[i] = master->backup_device.tx_byte_rates[i]; - data.devices[1].loss_rates[i] = master->backup_device.loss_rates[i]; + data.devices[1].rx_byte_rates[i] = + master->backup_device.rx_byte_rates[i]; + } + + data.tx_count = master->device_stats.tx_count; + data.rx_count = master->device_stats.rx_count; + data.tx_bytes = master->device_stats.tx_bytes; + data.rx_bytes = master->device_stats.rx_bytes; + for (i = 0; i < EC_RATE_COUNT; i++) { + data.tx_frame_rates[i] = + master->device_stats.tx_frame_rates[i]; + data.rx_frame_rates[i] = + master->device_stats.rx_frame_rates[i]; + data.tx_byte_rates[i] = + master->device_stats.tx_byte_rates[i]; + data.rx_byte_rates[i] = + master->device_stats.rx_byte_rates[i]; + data.loss_rates[i] = + master->device_stats.loss_rates[i]; } up(&master->device_sem); diff -r 8fa0571f9996 -r 69f2b2702336 master/device.c --- a/master/device.c Wed Nov 09 12:58:09 2011 +0100 +++ b/master/device.c Wed Nov 09 14:53:33 2011 +0100 @@ -54,12 +54,6 @@ } while (0) #endif -/** List of intervals for frame statistics [s]. - */ -static const unsigned int rate_intervals[] = { - 1, 10, 60 -}; - /*****************************************************************************/ /** Constructor. @@ -309,30 +303,6 @@ { struct sk_buff *skb = device->tx_skb[device->tx_ring_index]; - // frame statistics - if (unlikely(jiffies - device->stats_jiffies >= HZ)) { - unsigned int i; - u32 tx_frame_rate = - (u32) (device->tx_count - device->last_tx_count) * 1000; - u32 tx_byte_rate = - (device->tx_bytes - device->last_tx_bytes); - u64 loss = device->tx_count - device->rx_count; - s32 loss_rate = (s32) (loss - device->last_loss) * 1000; - for (i = 0; i < EC_RATE_COUNT; i++) { - unsigned int n = rate_intervals[i]; - device->tx_frame_rates[i] = - (device->tx_frame_rates[i] * (n - 1) + tx_frame_rate) / n; - device->tx_byte_rates[i] = - (device->tx_byte_rates[i] * (n - 1) + tx_byte_rate) / n; - device->loss_rates[i] = - (device->loss_rates[i] * (n - 1) + loss_rate) / n; - } - device->last_tx_count = device->tx_count; - device->last_tx_bytes = device->tx_bytes; - device->last_loss = loss; - device->stats_jiffies = jiffies; - } - // set the right length for the data skb->len = ETH_HLEN + size; @@ -350,7 +320,9 @@ #endif { device->tx_count++; + device->master->device_stats.tx_count++; device->tx_bytes += ETH_HLEN + size; + device->master->device_stats.tx_bytes += ETH_HLEN + size; #ifdef EC_DEBUG_IF ec_debug_send(&device->dbg, skb->data, ETH_HLEN + size); #endif @@ -375,16 +347,20 @@ // zero frame statistics device->tx_count = 0; + device->last_tx_count = 0; device->rx_count = 0; + device->last_rx_count = 0; + device->tx_bytes = 0; + device->last_tx_bytes = 0; + device->rx_bytes = 0; + device->last_rx_bytes = 0; device->tx_errors = 0; - device->tx_bytes = 0; - device->last_tx_count = 0; - device->last_tx_bytes = 0; - device->last_loss = 0; + for (i = 0; i < EC_RATE_COUNT; i++) { device->tx_frame_rates[i] = 0; + device->rx_frame_rates[i] = 0; device->tx_byte_rates[i] = 0; - device->loss_rates[i] = 0; + device->rx_byte_rates[i] = 0; } } @@ -479,6 +455,43 @@ device->poll(device->dev); } +/*****************************************************************************/ + +/** Update device statistics. + */ +void ec_device_update_stats( + ec_device_t *device /**< EtherCAT device */ + ) +{ + unsigned int i; + + u32 tx_frame_rate = + (u32) (device->tx_count - device->last_tx_count) * 1000; + u32 rx_frame_rate = + (u32) (device->rx_count - device->last_rx_count) * 1000; + u32 tx_byte_rate = + (device->tx_bytes - device->last_tx_bytes); + u32 rx_byte_rate = + (device->rx_bytes - device->last_rx_bytes); + + for (i = 0; i < EC_RATE_COUNT; i++) { + unsigned int n = rate_intervals[i]; + device->tx_frame_rates[i] = + (device->tx_frame_rates[i] * (n - 1) + tx_frame_rate) / n; + device->rx_frame_rates[i] = + (device->rx_frame_rates[i] * (n - 1) + rx_frame_rate) / n; + device->tx_byte_rates[i] = + (device->tx_byte_rates[i] * (n - 1) + tx_byte_rate) / n; + device->rx_byte_rates[i] = + (device->rx_byte_rates[i] * (n - 1) + rx_byte_rate) / n; + } + + device->last_tx_count = device->tx_count; + device->last_rx_count = device->rx_count; + device->last_tx_bytes = device->tx_bytes; + device->last_rx_bytes = device->rx_bytes; +} + /****************************************************************************** * Device interface *****************************************************************************/ @@ -593,6 +606,9 @@ } device->rx_count++; + device->master->device_stats.rx_count++; + device->rx_bytes += size; + device->master->device_stats.rx_bytes += size; if (unlikely(device->master->debug_level > 1)) { EC_MASTER_DBG(device->master, 2, "Received frame:\n"); diff -r 8fa0571f9996 -r 69f2b2702336 master/device.h --- a/master/device.h Wed Nov 09 12:58:09 2011 +0100 +++ b/master/device.h Wed Nov 09 14:53:33 2011 +0100 @@ -101,19 +101,26 @@ u64 tx_count; /**< Number of frames sent. */ u64 last_tx_count; /**< Number of frames sent of last statistics cycle. */ u64 rx_count; /**< Number of frames received. */ - u64 tx_bytes; /**< Number of frames sent. */ + u64 last_rx_count; /**< Number of frames received of last statistics + cycle. */ + u64 tx_bytes; /**< Number of bytes sent. */ u64 last_tx_bytes; /**< Number of bytes sent of last statistics cycle. */ + u64 rx_bytes; /**< Number of bytes received. */ + u64 last_rx_bytes; /**< Number of bytes received of last statistics cycle. + */ u64 tx_errors; /**< Number of transmit errors. */ - u64 last_loss; /**< Tx/Rx difference of last statistics cycle. */ unsigned int tx_frame_rates[EC_RATE_COUNT]; /**< Transmit rates in frames/s for different statistics cycle periods. */ + unsigned int rx_frame_rates[EC_RATE_COUNT]; /**< Receive rates in + frames/s for different + statistics cycle periods. */ unsigned int tx_byte_rates[EC_RATE_COUNT]; /**< Transmit rates in byte/s for different statistics cycle periods. */ - int loss_rates[EC_RATE_COUNT]; /**< Frame loss rates for different - statistics cycle periods. */ - unsigned long stats_jiffies; /**< Jiffies of last statistic cycle. */ + unsigned int rx_byte_rates[EC_RATE_COUNT]; /**< Receive rates in byte/s + for different statistics + cycle periods. */ #ifdef EC_DEBUG_IF ec_debug_t dbg; /**< debug device */ @@ -141,6 +148,7 @@ uint8_t *ec_device_tx_data(ec_device_t *); void ec_device_send(ec_device_t *, size_t); void ec_device_clear_stats(ec_device_t *); +void ec_device_update_stats(ec_device_t *); #ifdef EC_DEBUG_RING void ec_device_debug_ring_append(ec_device_t *, ec_debug_frame_dir_t, diff -r 8fa0571f9996 -r 69f2b2702336 master/ioctl.h --- a/master/ioctl.h Wed Nov 09 12:58:09 2011 +0100 +++ b/master/ioctl.h Wed Nov 09 14:53:33 2011 +0100 @@ -56,7 +56,7 @@ * * Increment this when changing the ioctl interface! */ -#define EC_IOCTL_VERSION_MAGIC 12 +#define EC_IOCTL_VERSION_MAGIC 14 // Command-line tool #define EC_IOCTL_MODULE EC_IOR(0x00, ec_ioctl_module_t) @@ -168,11 +168,22 @@ uint64_t tx_count; uint64_t rx_count; uint64_t tx_bytes; + uint64_t rx_bytes; uint64_t tx_errors; uint32_t tx_frame_rates[EC_RATE_COUNT]; + uint32_t rx_frame_rates[EC_RATE_COUNT]; uint32_t tx_byte_rates[EC_RATE_COUNT]; - int32_t loss_rates[EC_RATE_COUNT]; + uint32_t rx_byte_rates[EC_RATE_COUNT]; } devices[2]; + uint64_t tx_count; + uint64_t rx_count; + uint64_t tx_bytes; + uint64_t rx_bytes; + uint32_t tx_frame_rates[EC_RATE_COUNT]; + uint32_t rx_frame_rates[EC_RATE_COUNT]; + uint32_t tx_byte_rates[EC_RATE_COUNT]; + uint32_t rx_byte_rates[EC_RATE_COUNT]; + int32_t loss_rates[EC_RATE_COUNT]; uint64_t app_time; uint16_t ref_clock; } ec_ioctl_master_t; diff -r 8fa0571f9996 -r 69f2b2702336 master/master.c --- a/master/master.c Wed Nov 09 12:58:09 2011 +0100 +++ b/master/master.c Wed Nov 09 14:53:33 2011 +0100 @@ -82,6 +82,12 @@ #endif +/** List of intervals for statistics [s]. + */ +const unsigned int rate_intervals[] = { + 1, 10, 60 +}; + /*****************************************************************************/ void ec_master_clear_slave_configs(ec_master_t *); @@ -92,6 +98,8 @@ static int ec_master_eoe_thread(void *); #endif void ec_master_find_dc_ref_clock(ec_master_t *); +void ec_master_clear_device_stats(ec_master_t *); +void ec_master_update_device_stats(ec_master_t *); /*****************************************************************************/ @@ -134,6 +142,7 @@ master->main_mac = main_mac; master->backup_mac = backup_mac; + ec_master_clear_device_stats(master); sema_init(&master->device_sem, 1); @@ -1148,6 +1157,84 @@ } } +/*****************************************************************************/ + +/** Clears the common device statistics. + */ +void ec_master_clear_device_stats( + ec_master_t *master /**< EtherCAT master */ + ) +{ + unsigned int i; + + // zero frame statistics + master->device_stats.tx_count = 0; + master->device_stats.last_tx_count = 0; + master->device_stats.rx_count = 0; + master->device_stats.last_rx_count = 0; + master->device_stats.tx_bytes = 0; + master->device_stats.last_tx_bytes = 0; + master->device_stats.rx_bytes = 0; + master->device_stats.last_rx_bytes = 0; + master->device_stats.last_loss = 0; + + for (i = 0; i < EC_RATE_COUNT; i++) { + master->device_stats.tx_frame_rates[i] = 0; + master->device_stats.tx_byte_rates[i] = 0; + master->device_stats.loss_rates[i] = 0; + } +} + +/*****************************************************************************/ + +/** Updates the common device statistics. + */ +void ec_master_update_device_stats( + ec_master_t *master /**< EtherCAT master */ + ) +{ + ec_device_stats_t *s = &master->device_stats; + u32 tx_frame_rate, rx_frame_rate, tx_byte_rate, rx_byte_rate; + u64 loss; + s32 loss_rate; + unsigned int i; + + // frame statistics + if (likely(jiffies - s->jiffies < HZ)) { + return; + } + + tx_frame_rate = (u32) (s->tx_count - s->last_tx_count) * 1000; + rx_frame_rate = (u32) (s->rx_count - s->last_rx_count) * 1000; + tx_byte_rate = (s->tx_bytes - s->last_tx_bytes); + rx_byte_rate = (s->rx_bytes - s->last_rx_bytes); + loss = s->tx_count - s->rx_count; + loss_rate = (s32) (loss - s->last_loss) * 1000; + + for (i = 0; i < EC_RATE_COUNT; i++) { + unsigned int n = rate_intervals[i]; + s->tx_frame_rates[i] = + (s->tx_frame_rates[i] * (n - 1) + tx_frame_rate) / n; + s->rx_frame_rates[i] = + (s->rx_frame_rates[i] * (n - 1) + rx_frame_rate) / n; + s->tx_byte_rates[i] = + (s->tx_byte_rates[i] * (n - 1) + tx_byte_rate) / n; + s->rx_byte_rates[i] = + (s->rx_byte_rates[i] * (n - 1) + rx_byte_rate) / n; + s->loss_rates[i] = + (s->loss_rates[i] * (n - 1) + loss_rate) / n; + + } + s->last_tx_count = s->tx_count; + s->last_rx_count = s->rx_count; + s->last_tx_bytes = s->tx_bytes; + s->last_rx_bytes = s->rx_bytes; + + ec_device_update_stats(&master->main_device); + ec_device_update_stats(&master->backup_device); + + s->jiffies = jiffies; +} /*****************************************************************************/ @@ -2129,6 +2216,7 @@ if (master->backup_device.dev) { ec_device_poll(&master->backup_device); } + ec_master_update_device_stats(master); // dequeue all datagrams that timed out list_for_each_entry_safe(datagram, next, &master->datagram_queue, queue) { diff -r 8fa0571f9996 -r 69f2b2702336 master/master.h --- a/master/master.h Wed Nov 09 12:58:09 2011 +0100 +++ b/master/master.h Wed Nov 09 14:53:33 2011 +0100 @@ -137,6 +137,39 @@ /*****************************************************************************/ +/** Device statistics. + */ +typedef struct { + u64 tx_count; /**< Number of frames sent. */ + u64 last_tx_count; /**< Number of frames sent of last statistics cycle. */ + u64 rx_count; /**< Number of frames received. */ + u64 last_rx_count; /**< Number of frames received of last statistics + cycle. */ + u64 tx_bytes; /**< Number of bytes sent. */ + u64 last_tx_bytes; /**< Number of bytes sent of last statistics cycle. */ + u64 rx_bytes; /**< Number of bytes received. */ + u64 last_rx_bytes; /**< Number of bytes received of last statistics cycle. + */ + u64 last_loss; /**< Tx/Rx difference of last statistics cycle. */ + unsigned int tx_frame_rates[EC_RATE_COUNT]; /**< Transmit rates in + frames/s for different + statistics cycle periods. */ + unsigned int rx_frame_rates[EC_RATE_COUNT]; /**< Receive rates in + frames/s for different + statistics cycle periods. */ + unsigned int tx_byte_rates[EC_RATE_COUNT]; /**< Transmit rates in byte/s + for different statistics + cycle periods. */ + unsigned int rx_byte_rates[EC_RATE_COUNT]; /**< Receive rates in byte/s + for different statistics + cycle periods. */ + int loss_rates[EC_RATE_COUNT]; /**< Frame loss rates for different + statistics cycle periods. */ + unsigned long jiffies; /**< Jiffies of last statistic cycle. */ +} ec_device_stats_t; + +/*****************************************************************************/ + /** EtherCAT master. * * Manages slaves, domains and IO. @@ -159,6 +192,7 @@ ec_device_t backup_device; /**< EtherCAT backup device. */ const uint8_t *backup_mac; /**< MAC address of backup device. */ struct semaphore device_sem; /**< Device semaphore. */ + ec_device_stats_t device_stats; /**< Device statistics. */ ec_fsm_master_t fsm; /**< Master state machine. */ ec_datagram_t fsm_datagram; /**< Datagram used for state machines. */ @@ -309,6 +343,8 @@ void ec_master_internal_send_cb(void *); void ec_master_internal_receive_cb(void *); -/*****************************************************************************/ - -#endif +extern const unsigned int rate_intervals[EC_RATE_COUNT]; // see master.c + +/*****************************************************************************/ + +#endif diff -r 8fa0571f9996 -r 69f2b2702336 tool/CommandMaster.cpp --- a/tool/CommandMaster.cpp Wed Nov 09 12:58:09 2011 +0100 +++ b/tool/CommandMaster.cpp Wed Nov 09 14:53:33 2011 +0100 @@ -114,12 +114,6 @@ && data.devices[i].address[5] == 0x00) { cout << "None."; } else { - unsigned int lost = - data.devices[i].tx_count - data.devices[i].rx_count; - if (lost == 1) { - // allow one frame travelling - lost = 0; - } cout << hex << setfill('0') << setw(2) << (unsigned int) data.devices[i].address[0] << ":" @@ -139,11 +133,12 @@ << (data.devices[i].link_state ? "UP" : "DOWN") << endl << " Tx frames: " << data.devices[i].tx_count << endl + << " Tx bytes: " + << data.devices[i].tx_bytes << endl << " Rx frames: " << data.devices[i].rx_count << endl - << " Lost frames: " << lost << endl - << " Tx bytes: " - << data.devices[i].tx_bytes << endl + << " Rx bytes: " + << data.devices[i].rx_bytes << endl << " Tx errors: " << data.devices[i].tx_errors << endl << " Tx frame rate [1/s]: " @@ -166,33 +161,106 @@ } } cout << endl - << " Loss rate [1/s]: " - << setprecision(0) << fixed; - for (j = 0; j < EC_RATE_COUNT; j++) { - cout << setw(ColWidth) - << data.devices[i].loss_rates[j] / 1000.0; + << " Rx frame rate [1/s]: " + << setfill(' ') << setprecision(0) << fixed; + for (j = 0; j < EC_RATE_COUNT; j++) { + cout << setw(ColWidth) + << data.devices[i].rx_frame_rates[j] / 1000.0; if (j < EC_RATE_COUNT - 1) { cout << " "; } } cout << endl - << " Frame loss [%]: " + << " Rx rate [KByte/s]: " << setprecision(1) << fixed; for (j = 0; j < EC_RATE_COUNT; j++) { - double perc = 0.0; - if (data.devices[i].tx_frame_rates[j]) { - perc = 100.0 * data.devices[i].loss_rates[j] / - data.devices[i].tx_frame_rates[j]; - } - cout << setw(ColWidth) << perc; + cout << setw(ColWidth) + << data.devices[i].rx_byte_rates[j] / 1024.0; if (j < EC_RATE_COUNT - 1) { cout << " "; } } cout << setprecision(0) << endl; } - cout << endl; - } + } + unsigned int lost = data.tx_count - data.rx_count; + if (lost == 1) { + // allow one frame travelling + lost = 0; + } + cout << " Common:" << endl + << " Tx frames: " + << data.tx_count << endl + << " Tx bytes: " + << data.tx_bytes << endl + << " Rx frames: " + << data.rx_count << endl + << " Rx bytes: " + << data.rx_bytes << endl + << " Lost frames: " << lost << endl + << " Tx frame rate [1/s]: " + << setfill(' ') << setprecision(0) << fixed; + for (j = 0; j < EC_RATE_COUNT; j++) { + cout << setw(ColWidth) + << data.tx_frame_rates[j] / 1000.0; + if (j < EC_RATE_COUNT - 1) { + cout << " "; + } + } + cout << endl + << " Tx rate [KByte/s]: " + << setprecision(1) << fixed; + for (j = 0; j < EC_RATE_COUNT; j++) { + cout << setw(ColWidth) + << data.tx_byte_rates[j] / 1024.0; + if (j < EC_RATE_COUNT - 1) { + cout << " "; + } + } + cout << endl + << " Rx frame rate [1/s]: " + << setfill(' ') << setprecision(0) << fixed; + for (j = 0; j < EC_RATE_COUNT; j++) { + cout << setw(ColWidth) + << data.rx_frame_rates[j] / 1000.0; + if (j < EC_RATE_COUNT - 1) { + cout << " "; + } + } + cout << endl + << " Rx rate [KByte/s]: " + << setprecision(1) << fixed; + for (j = 0; j < EC_RATE_COUNT; j++) { + cout << setw(ColWidth) + << data.rx_byte_rates[j] / 1024.0; + if (j < EC_RATE_COUNT - 1) { + cout << " "; + } + } + cout << endl + << " Loss rate [1/s]: " + << setprecision(0) << fixed; + for (j = 0; j < EC_RATE_COUNT; j++) { + cout << setw(ColWidth) + << data.loss_rates[j] / 1000.0; + if (j < EC_RATE_COUNT - 1) { + cout << " "; + } + } + cout << endl + << " Frame loss [%]: " + << setprecision(1) << fixed; + for (j = 0; j < EC_RATE_COUNT; j++) { + double perc = 0.0; + if (data.tx_frame_rates[j]) { + perc = 100.0 * data.loss_rates[j] / data.tx_frame_rates[j]; + } + cout << setw(ColWidth) << perc; + if (j < EC_RATE_COUNT - 1) { + cout << " "; + } + } + cout << setprecision(0) << endl; cout << " Distributed clocks:" << endl << " Reference clock: ";