Frame statistics in 'ethercat master' output.
This commit is contained in:
parent
0059ab2e38
commit
697124e23c
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue