diff --git a/TODO b/TODO index 5aeff333..f57b246f 100644 --- a/TODO +++ b/TODO @@ -44,8 +44,6 @@ Version 1.5.0: * ethercat tool: - Data type abbreviations. - Implement ranges for slaves and domains. -* Output send errors in frame statistics. -* Output tx rate [bytes/s] in frame statistics. Future issues: diff --git a/master/cdev.c b/master/cdev.c index 90d07fdc..aa81c01c 100644 --- a/master/cdev.c +++ b/master/cdev.c @@ -212,8 +212,13 @@ 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; + data.devices[0].tx_bytes = master->main_device.tx_bytes; + data.devices[0].tx_errors = master->main_device.tx_errors; for (i = 0; i < EC_RATE_COUNT; i++) { - data.devices[0].tx_rates[i] = master->main_device.tx_rates[i]; + data.devices[0].tx_frame_rates[i] = + master->main_device.tx_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]; } @@ -227,8 +232,13 @@ 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; + data.devices[1].tx_bytes = master->backup_device.tx_bytes; + data.devices[1].tx_errors = master->backup_device.tx_errors; for (i = 0; i < EC_RATE_COUNT; i++) { - data.devices[1].tx_rates[i] = master->backup_device.tx_rates[i]; + data.devices[1].tx_frame_rates[i] = + master->backup_device.tx_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]; } diff --git a/master/device.c b/master/device.c index 9e195727..18ce7808 100644 --- a/master/device.c +++ b/master/device.c @@ -198,15 +198,9 @@ void ec_device_detach( device->module = NULL; device->open = 0; 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; + + ec_device_clear_stats(device); + for (i = 0; i < EC_TX_RING_SIZE; i++) device->tx_skb[i]->dev = NULL; } @@ -222,7 +216,6 @@ int ec_device_open( ) { int ret; - unsigned int i; if (!device->dev) { EC_ERR("No net_device to open!\n"); @@ -235,15 +228,8 @@ 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; + + ec_device_clear_stats(device); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) ret = device->dev->netdev_ops->ndo_open(device->dev); @@ -324,18 +310,23 @@ void ec_device_send( // frame statistics if (unlikely(jiffies - device->stats_jiffies >= HZ)) { unsigned int i; - unsigned int tx_rate = + unsigned int tx_frame_rate = (device->tx_count - device->last_tx_count) * 1000; + unsigned int tx_byte_rate = + (device->tx_bytes - device->last_tx_bytes) * 1000; 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->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; } @@ -357,6 +348,7 @@ void ec_device_send( #endif { device->tx_count++; + device->tx_bytes += ETH_HLEN + size; #ifdef EC_DEBUG_IF ec_debug_send(&device->dbg, skb->data, ETH_HLEN + size); #endif @@ -364,6 +356,8 @@ void ec_device_send( ec_device_debug_ring_append( device, TX, skb->data + ETH_HLEN, size); #endif + } else { + device->tx_errors++; } } @@ -380,10 +374,14 @@ void ec_device_clear_stats( // zero frame statistics device->tx_count = 0; device->rx_count = 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_rates[i] = 0; + device->tx_frame_rates[i] = 0; + device->tx_byte_rates[i] = 0; device->loss_rates[i] = 0; } } diff --git a/master/device.h b/master/device.h index fed949b2..c242a831 100644 --- a/master/device.h +++ b/master/device.h @@ -100,10 +100,18 @@ struct ec_device // Frame statistics unsigned int tx_count; /**< Number of frames sent. */ unsigned int rx_count; /**< Number of frames received. */ + unsigned int tx_bytes; /**< Number of frames sent. */ + unsigned int tx_errors; /**< Number of transmit errors. */ + unsigned int tx_frame_rates[EC_RATE_COUNT]; /**< Transmit 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 last_tx_count; /**< Number of frames sent of last statistics cycle. */ - unsigned int tx_rates[EC_RATE_COUNT]; /**< Transmit rates for different - statistics cycle periods. */ + unsigned int last_tx_bytes; /**< Number of bytes sent of last statistics + cycle. */ int last_loss; /**< Tx/Rx difference of last statistics cycle. */ int loss_rates[EC_RATE_COUNT]; /**< Frame loss rates for different statistics cycle periods. */ diff --git a/master/ioctl.h b/master/ioctl.h index 25e0771b..e93328f9 100644 --- a/master/ioctl.h +++ b/master/ioctl.h @@ -157,13 +157,16 @@ typedef struct { uint8_t phase; uint8_t active; uint8_t scan_busy; - struct { + struct ec_ioctl_device { uint8_t address[6]; uint8_t attached; uint8_t link_state; uint32_t tx_count; uint32_t rx_count; - uint32_t tx_rates[EC_RATE_COUNT]; + uint32_t tx_bytes; + uint32_t tx_errors; + uint32_t tx_frame_rates[EC_RATE_COUNT]; + uint32_t tx_byte_rates[EC_RATE_COUNT]; int32_t loss_rates[EC_RATE_COUNT]; } devices[2]; uint64_t app_time; diff --git a/tool/CommandMaster.cpp b/tool/CommandMaster.cpp index 2f806a1c..e18c313e 100644 --- a/tool/CommandMaster.cpp +++ b/tool/CommandMaster.cpp @@ -131,16 +131,29 @@ void CommandMaster::execute(const StringVector &args) << (data.devices[i].link_state ? "UP" : "DOWN") << endl << " Tx count: " << data.devices[i].tx_count << endl << " Rx count: " << data.devices[i].rx_count << endl - << " Tx rate [frames/s]: " + << " Tx bytes: " << data.devices[i].tx_bytes << endl + << " Tx errors: " << data.devices[i].tx_errors << endl + << " Tx frame rate [1/s]: " << setfill(' ') << setprecision(0) << fixed; for (j = 0; j < EC_RATE_COUNT; j++) { - cout << setw(5) << data.devices[i].tx_rates[j] / 1000.0; + cout << + setw(5) << data.devices[i].tx_frame_rates[j] / 1000.0; if (j < EC_RATE_COUNT - 1) { cout << " "; } } cout << endl - << " Loss rate [frames/s]: " + << " Tx rate [KByte/s]: " + << setprecision(0) << fixed; + for (j = 0; j < EC_RATE_COUNT; j++) { + cout << + setw(5) << data.devices[i].tx_byte_rates[j] / 1000.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(5) << data.devices[i].loss_rates[j] / 1000.0; @@ -149,13 +162,13 @@ void CommandMaster::execute(const StringVector &args) } } cout << endl - << " Frame loss [%]: " + << " Frame loss [%]: " << setprecision(1) << fixed; for (j = 0; j < EC_RATE_COUNT; j++) { double perc = 0.0; - if (data.devices[i].tx_rates[j]) { + if (data.devices[i].tx_frame_rates[j]) { perc = 100.0 * data.devices[i].loss_rates[j] / - data.devices[i].tx_rates[j]; + data.devices[i].tx_frame_rates[j]; } cout << setw(5) << perc; if (j < EC_RATE_COUNT - 1) {