Adjusted frame statistics for the use with two devices.
--- 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);
--- 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");
--- 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,
--- 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;
--- 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) {
--- 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
--- 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: ";