From de674558634a83daababb62fe84e0388bde15033 Mon Sep 17 00:00:00 2001 From: Florian Pose <fp@igh-essen.com> Date: Sun, 7 Mar 2010 23:55:51 +0100 Subject: [PATCH] Frame statistics in 'ethercat master' output. --- master/cdev.c | 9 +++++++++ master/device.c | 39 +++++++++++++++++++++++++++++++++++++++ master/device.h | 5 +++++ master/globals.h | 3 +++ master/ioctl.h | 4 +++- tool/CommandMaster.cpp | 33 +++++++++++++++++++++++++++++++-- 6 files changed, 90 insertions(+), 3 deletions(-) diff --git a/master/cdev.c b/master/cdev.c index 42014dd2..90d07fdc 100644 --- a/master/cdev.c +++ b/master/cdev.c @@ -184,6 +184,7 @@ int ec_cdev_ioctl_master( ) { ec_ioctl_master_t data; + unsigned int i; if (down_interruptible(&master->master_sem)) return -EINTR; @@ -211,6 +212,10 @@ int ec_cdev_ioctl_master( 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 @@ int ec_cdev_ioctl_master( 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 --git a/master/device.c b/master/device.c index d639d0c7..daf7cca1 100644 --- a/master/device.c +++ b/master/device.c @@ -54,6 +54,10 @@ } while (0) #endif +static const unsigned int rate_intervals[] = { + 1, 10, 60 +}; + /*****************************************************************************/ /** Constructor. @@ -196,6 +200,13 @@ void ec_device_detach( 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 ec_device_open( ) { int ret; + unsigned int i; if (!device->dev) { EC_ERR("No net_device to open!\n"); @@ -225,6 +237,13 @@ int ec_device_open( 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 @@ void ec_device_send( { 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 --git a/master/device.h b/master/device.h index ebc7609d..c5c8882b 100644 --- a/master/device.h +++ b/master/device.h @@ -98,6 +98,11 @@ struct ec_device 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 --git a/master/globals.h b/master/globals.h index fdb34f67..e17a7547 100644 --- a/master/globals.h +++ b/master/globals.h @@ -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 --git a/master/ioctl.h b/master/ioctl.h index 84831b57..25e0771b 100644 --- a/master/ioctl.h +++ b/master/ioctl.h @@ -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 @@ typedef struct { 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 --git a/tool/CommandMaster.cpp b/tool/CommandMaster.cpp index c8ed9825..28c42967 100644 --- a/tool/CommandMaster.cpp +++ b/tool/CommandMaster.cpp @@ -69,7 +69,7 @@ void CommandMaster::execute(const StringVector &args) { 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 @@ void CommandMaster::execute(const StringVector &args) << " 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; } -- GitLab