# HG changeset patch # User Florian Pose # Date 1268002551 -3600 # Node ID a56bd34e20a126722847e409cd2806cc63372559 # Parent fa112b8a371b8629cf969cf161f8a3acb2045efe Frame statistics in 'ethercat master' output. diff -r fa112b8a371b -r a56bd34e20a1 master/cdev.c --- a/master/cdev.c Sun Mar 07 23:12:30 2010 +0100 +++ b/master/cdev.c Sun Mar 07 23:55:51 2010 +0100 @@ -184,6 +184,7 @@ ) { ec_ioctl_master_t data; + unsigned int i; if (down_interruptible(&master->master_sem)) return -EINTR; @@ -211,6 +212,10 @@ data.devices[0].link_state = master->main_device.link_state ? 1 : 0; data.devices[0].tx_count = master->main_device.tx_count; data.devices[0].rx_count = master->main_device.rx_count; + for (i = 0; i < EC_RATE_COUNT; i++) { + data.devices[0].tx_rates[i] = master->main_device.tx_rates[i]; + data.devices[0].loss_rates[i] = master->main_device.loss_rates[i]; + } if (master->backup_device.dev) { memcpy(data.devices[1].address, @@ -222,6 +227,10 @@ data.devices[1].link_state = master->backup_device.link_state ? 1 : 0; data.devices[1].tx_count = master->backup_device.tx_count; data.devices[1].rx_count = master->backup_device.rx_count; + for (i = 0; i < EC_RATE_COUNT; i++) { + data.devices[1].tx_rates[i] = master->backup_device.tx_rates[i]; + data.devices[1].loss_rates[i] = master->backup_device.loss_rates[i]; + } up(&master->device_sem); diff -r fa112b8a371b -r a56bd34e20a1 master/device.c --- a/master/device.c Sun Mar 07 23:12:30 2010 +0100 +++ b/master/device.c Sun Mar 07 23:55:51 2010 +0100 @@ -54,6 +54,10 @@ } while (0) #endif +static const unsigned int rate_intervals[] = { + 1, 10, 60 +}; + /*****************************************************************************/ /** Constructor. @@ -196,6 +200,13 @@ device->link_state = 0; // down device->tx_count = 0; device->rx_count = 0; + device->last_tx_count = 0; + device->last_loss = 0; + for (i = 0; i < EC_RATE_COUNT; i++) { + device->tx_rates[i] = 0; + device->loss_rates[i] = 0; + } + device->stats_jiffies = 0; for (i = 0; i < EC_TX_RING_SIZE; i++) device->tx_skb[i]->dev = NULL; } @@ -211,6 +222,7 @@ ) { int ret; + unsigned int i; if (!device->dev) { EC_ERR("No net_device to open!\n"); @@ -225,6 +237,13 @@ device->link_state = 0; device->tx_count = 0; device->rx_count = 0; + device->last_tx_count = 0; + device->last_loss = 0; + for (i = 0; i < EC_RATE_COUNT; i++) { + device->tx_rates[i] = 0; + device->loss_rates[i] = 0; + } + device->stats_jiffies = 0; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) ret = device->dev->netdev_ops->ndo_open(device->dev); @@ -302,6 +321,26 @@ { struct sk_buff *skb = device->tx_skb[device->tx_ring_index]; + // frame statistics + if (unlikely(jiffies - device->stats_jiffies >= HZ)) { + unsigned int i; + unsigned int tx_rate = device->tx_count - device->last_tx_count; + int loss = device->tx_count - device->rx_count; + int loss_rate = (loss - device->last_loss) * 1000; + for (i = 0; i < EC_RATE_COUNT; i++) { + unsigned int n = rate_intervals[i]; + device->tx_rates[i] = + device->tx_rates[i] * (n - 1) + + tx_rate * n; + device->loss_rates[i] = + device->loss_rates[i] * (n - 1) + + loss_rate * n; + } + device->last_tx_count = device->tx_count; + device->last_loss = loss; + device->stats_jiffies += HZ; + } + if (unlikely(!device->link_state)) // Link down return; diff -r fa112b8a371b -r a56bd34e20a1 master/device.h --- a/master/device.h Sun Mar 07 23:12:30 2010 +0100 +++ b/master/device.h Sun Mar 07 23:55:51 2010 +0100 @@ -98,6 +98,11 @@ unsigned long jiffies_poll; /**< jiffies of last poll */ unsigned int tx_count; /**< number of frames sent */ unsigned int rx_count; /**< number of frames received */ + unsigned int last_tx_count; + unsigned int tx_rates[EC_RATE_COUNT]; + int last_loss; /**< Tx/Rx difference of last cycle. */ + int loss_rates[EC_RATE_COUNT]; + unsigned long stats_jiffies; #ifdef EC_DEBUG_IF ec_debug_t dbg; /**< debug device */ #endif diff -r fa112b8a371b -r a56bd34e20a1 master/globals.h --- a/master/globals.h Sun Mar 07 23:12:30 2010 +0100 +++ b/master/globals.h Sun Mar 07 23:55:51 2010 +0100 @@ -70,6 +70,9 @@ /** Maximum SII size in words, to avoid infinite reading. */ #define EC_MAX_SII_SIZE 4096 +/** Number of statistic rate intervals to maintain. */ +#define EC_RATE_COUNT 3 + /****************************************************************************** * EtherCAT protocol *****************************************************************************/ diff -r fa112b8a371b -r a56bd34e20a1 master/ioctl.h --- a/master/ioctl.h Sun Mar 07 23:12:30 2010 +0100 +++ b/master/ioctl.h Sun Mar 07 23:55:51 2010 +0100 @@ -56,7 +56,7 @@ * * Increment this when changing the ioctl interface! */ -#define EC_IOCTL_VERSION_MAGIC 3 +#define EC_IOCTL_VERSION_MAGIC 4 // Command-line tool #define EC_IOCTL_MODULE EC_IOR(0x00, ec_ioctl_module_t) @@ -163,6 +163,8 @@ uint8_t link_state; uint32_t tx_count; uint32_t rx_count; + uint32_t tx_rates[EC_RATE_COUNT]; + int32_t loss_rates[EC_RATE_COUNT]; } devices[2]; uint64_t app_time; uint16_t ref_clock; diff -r fa112b8a371b -r a56bd34e20a1 tool/CommandMaster.cpp --- a/tool/CommandMaster.cpp Sun Mar 07 23:12:30 2010 +0100 +++ b/tool/CommandMaster.cpp Sun Mar 07 23:55:51 2010 +0100 @@ -69,7 +69,7 @@ { ec_ioctl_master_t data; stringstream err; - unsigned int i; + unsigned int i, j; time_t epoch; char time_str[MAX_TIME_STR_SIZE + 1]; size_t time_str_size; @@ -130,7 +130,36 @@ << " Link: " << (data.devices[i].link_state ? "UP" : "DOWN") << endl << " Tx count: " << data.devices[i].tx_count << endl - << " Rx count: " << data.devices[i].rx_count; + << " Rx count: " << data.devices[i].rx_count << endl + << " Tx rates: "; + for (j = 0; j < EC_RATE_COUNT; j++) { + cout << data.devices[i].tx_rates[j] / 1000; + if (j < EC_RATE_COUNT - 1) { + cout << " "; + } + } + cout << endl + << " Loss rates: "; + for (j = 0; j < EC_RATE_COUNT; j++) { + cout << data.devices[i].loss_rates[j] / 1000; + if (j < EC_RATE_COUNT - 1) { + cout << " "; + } + } + cout << endl + << " Loss percentages: " << setprecision(1); + for (j = 0; j < EC_RATE_COUNT; j++) { + double perc = 0.0; + if (data.devices[i].tx_rates[j]) { + perc = 100.0 * data.devices[i].loss_rates[j] / + data.devices[i].tx_rates[j]; + } + cout << perc; + if (j < EC_RATE_COUNT - 1) { + cout << " "; + } + } + cout << setprecision(0) << endl; } cout << endl; }