Root/tools/usbperf/usbperf.c

Source at commit 49e7c83796bc04941e9dbcec69bc0751563ff4d4 created 2 years 6 months ago.
By Werner Almesberger, atusb/: use ""VDD" symbol from kicad-libs
1/*
2 * usbperf/usbperf.c - Measure the rate of control transfers a device can do
3 *
4 * Written 2011 by Werner Almesberger
5 * Copyright 2011 Werner Almesberger
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13
14#include <stdlib.h>
15#include <stdio.h>
16#include <unistd.h>
17#include <dirent.h>
18#include <sys/time.h>
19
20#include <usb.h>
21
22#include "usbopen.h"
23
24
25#define SYSFS_USB_BASE "/sys/bus/usb/devices"
26
27
28static void speed(usb_dev_handle *dev)
29{
30    struct usb_device *device = usb_device(dev);
31    struct usb_bus *bus = device->bus;
32    DIR *dir;
33    const struct dirent *de;
34    char buf[1000]; /* @@@ plenty :) */
35    FILE *file;
36    int res, devnum;
37    float speed;
38
39    dir = opendir(SYSFS_USB_BASE);
40    if (!dir) {
41        perror(SYSFS_USB_BASE);
42        exit(1);
43    }
44
45    while ((de = readdir(dir))) {
46        if (atoi(de->d_name) != atoi(bus->dirname))
47            continue;
48
49        sprintf(buf, SYSFS_USB_BASE "/%s/devnum", de->d_name);
50        file = fopen(buf, "r");
51        if (!file)
52            continue;
53        res = fscanf(file, "%d", &devnum);
54        fclose(file);
55
56        if (res != 1 || devnum != atoi(device->filename))
57            continue;
58
59        sprintf(buf, SYSFS_USB_BASE "/%s/speed", de->d_name);
60        file = fopen(buf, "r");
61        if (!file)
62            continue;
63        res = fscanf(file, "%f", &speed);
64        fclose(file);
65
66        printf("%g Mbps\n", speed);
67    }
68    closedir(dir);
69}
70
71
72static void rounds(usb_dev_handle *dev, int n)
73{
74    struct timeval t0, t1, t2;
75    double s = 0, d;
76    char buf;
77    int i, res;
78
79    gettimeofday(&t0, NULL);
80    for (i = 0; i != n; i++) {
81        gettimeofday(&t1, NULL);
82        /* GET_CONFIGURATION */
83        res = usb_control_msg(dev, USB_ENDPOINT_IN | USB_RECIP_DEVICE,
84            USB_REQ_GET_CONFIGURATION, 0, 0, &buf, 1, 1000);
85            if (res < 0)
86            fprintf(stderr, "usb_control_msg returns %d\n", res);
87        gettimeofday(&t2, NULL);
88        s += (t2.tv_sec-t1.tv_sec)+(t2.tv_usec-t1.tv_usec)*1e-6;
89
90    }
91    d = (t2.tv_sec-t0.tv_sec)+(t2.tv_usec-t0.tv_usec)*1e-6;
92    printf("Overall: %.3f ms/req\n", d/n*1000.0);
93    printf("Each: %.3f ms/req\n", s/n*1000.0);
94}
95
96
97static void usage(const char *name)
98{
99    fprintf(stderr,
100"usage: %s [vendor]:[product] [rounds]\n"
101  , name);
102    exit(1);
103}
104
105
106int main(int argc, char **argv)
107{
108    usb_dev_handle *dev;
109    int n = 1000;
110
111    switch (argc) {
112    case 2:
113        break;
114    case 3:
115        n = atoi(argv[2]);
116        if (n <= 0)
117            usage(*argv);
118        break;
119    default:
120        usage(*argv);
121    }
122
123    parse_usb_id(argv[1]);
124    dev = open_usb(0, 0);
125    if (!dev)
126        return 1;
127
128    speed(dev);
129    rounds(dev, n);
130
131    return 0;
132}
133

Archive Download this file



interactive