canbusload: support busload visualization

Add '-v' option for visualize busload, the output shows a moving
histogram of the past 90 seconds.

canbusload 2024-09-23 17:19:33 (exact bitstuffing)
 can0@500k   487   55558   31048       0  99% |XXXXXXXXXXXXXXXXXXX.|
100%|..........................................................................................
 95%|..............................................................................XXXXXXXXXXXX
 90%|.............................................................................XXXXXXXXXXXXX
 85%|.............................................................................XXXXXXXXXXXXX
 80%|.............................................................................XXXXXXXXXXXXX
 75%|.............................................................................XXXXXXXXXXXXX
 70%|.............................................................................XXXXXXXXXXXXX
 65%|.............................................................................XXXXXXXXXXXXX
 60%|............................................................................XXXXXXXXXXXXXX
 55%|............................................................................XXXXXXXXXXXXXX
 50%|............................................................................XXXXXXXXXXXXXX
 45%|............................................................................XXXXXXXXXXXXXX
 40%|............................................................................XXXXXXXXXXXXXX
 35%|.........................................XXX................................XXXXXXXXXXXXXX
 30%|.........................................XXXX...............................XXXXXXXXXXXXXX
 25%|........................................XXXXXX.............................XXXXXXXXXXXXXXX
 20%|XXXXXXXX...............................XXXXXXXXXXXXXXXXX....XXXXXXXXXXX...XXXXXXXXXXXXXXXX
 15%|XXXXXXXXX.............................XXXXXXXXXXXXXXXXXXXX.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
 10%|XXXXXXXXX.XXXXXXXXXXXXXXXXXXX..XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  5%|XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Signed-off-by: Zhu Yi <yi.zhu5@cn.bosch.com>
Signed-off-by: Hubert Streidl <hubert.streidl@de.bosch.com>
Signed-off-by: Mark Jonas <mark.jonas@de.bosch.com>
Link: https://lore.kernel.org/r/20250120162332.19157-3-mark.jonas@de.bosch.com
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
pull/571/head
Zhu Yi 2025-01-20 17:23:32 +01:00 committed by Marc Kleine-Budde
parent b85418d75c
commit b3da2f62b9
1 changed files with 36 additions and 4 deletions

View File

@ -74,6 +74,7 @@
#define PERCENTRES 5 /* resolution in percent for bargraph */ #define PERCENTRES 5 /* resolution in percent for bargraph */
#define NUMBAR (100 / PERCENTRES) /* number of bargraph elements */ #define NUMBAR (100 / PERCENTRES) /* number of bargraph elements */
#define BRSTRLEN 20 #define BRSTRLEN 20
#define VISUAL_WINDOW 90 /* window width for visualization */
/* /*
* Inspired from * Inspired from
@ -111,19 +112,22 @@ static struct {
unsigned int load_1m; unsigned int load_1m;
unsigned int load_5m; unsigned int load_5m;
unsigned int load_15m; unsigned int load_15m;
unsigned int loads[VISUAL_WINDOW];
unsigned int index;
} stat[MAXDEVS + 1]; } stat[MAXDEVS + 1];
static volatile int running = 1; static volatile int running = 1;
static volatile sig_atomic_t signal_num; static volatile sig_atomic_t signal_num;
static int max_devname_len; /* to prevent frazzled device name output */ static int max_devname_len; /* to prevent frazzled device name output */
static int max_bitratestr_len; static int max_bitratestr_len;
static int currmax; static unsigned int currmax;
static unsigned char redraw; static unsigned char redraw;
static unsigned char timestamp; static unsigned char timestamp;
static unsigned char color; static unsigned char color;
static unsigned char bargraph; static unsigned char bargraph;
static bool statistic; static bool statistic;
static bool reset; static bool reset;
static bool visualize;
static enum cfl_mode mode = CFL_WORSTCASE; static enum cfl_mode mode = CFL_WORSTCASE;
static char *prg; static char *prg;
static struct termios old; static struct termios old;
@ -141,6 +145,7 @@ static void print_usage(char *prg)
fprintf(stderr, " -i (ignore bitstuffing in bandwidth calculation)\n"); fprintf(stderr, " -i (ignore bitstuffing in bandwidth calculation)\n");
fprintf(stderr, " -e (exact calculation of stuffed bits)\n"); fprintf(stderr, " -e (exact calculation of stuffed bits)\n");
fprintf(stderr, " -s (show statistics, press 'r' to reset)\n"); fprintf(stderr, " -s (show statistics, press 'r' to reset)\n");
fprintf(stderr, " -v (show busload visualization)\n");
fprintf(stderr, "\n"); fprintf(stderr, "\n");
fprintf(stderr, "Up to %d CAN interfaces with mandatory bitrate can be specified on the \n", MAXDEVS); fprintf(stderr, "Up to %d CAN interfaces with mandatory bitrate can be specified on the \n", MAXDEVS);
fprintf(stderr, "commandline in the form: <ifname>@<bitrate>[,<dbitrate>]\n"); fprintf(stderr, "commandline in the form: <ifname>@<bitrate>[,<dbitrate>]\n");
@ -203,7 +208,7 @@ static unsigned int calc_load(unsigned int load_fp,
static void printstats(int signo) static void printstats(int signo)
{ {
int i, j, percent; unsigned int i, j, k, percent, index;
if (redraw) if (redraw)
printf("%s", CSR_HOME); printf("%s", CSR_HOME);
@ -315,6 +320,28 @@ static void printstats(int signo)
printf("|"); printf("|");
} }
if (visualize) {
stat[i].loads[stat[i].index] = percent;
stat[i].index = (stat[i].index + 1) % VISUAL_WINDOW;
printf("\n");
for (j = 0; j < NUMBAR; j++) {
printf("%3d%%|", (NUMBAR - j) * PERCENTRES);
index = stat[i].index;
for (k = 0; k < VISUAL_WINDOW; k++) {
percent = stat[i].loads[index];
if ((percent / PERCENTRES) >= (NUMBAR - j))
printf("X");
else
printf(".");
index = (index + 1) % VISUAL_WINDOW;
}
printf("\n");
}
}
if (color) if (color)
printf("%s", ATTRESET); printf("%s", ATTRESET);
@ -353,7 +380,8 @@ int main(int argc, char **argv)
struct canfd_frame frame; struct canfd_frame frame;
struct iovec iov; struct iovec iov;
struct msghdr msg; struct msghdr msg;
int nbytes, i; unsigned int i;
int nbytes;
int have_anydev = 0; int have_anydev = 0;
unsigned int anydev_bitrate = 0; unsigned int anydev_bitrate = 0;
@ -375,7 +403,7 @@ int main(int argc, char **argv)
prg = basename(argv[0]); prg = basename(argv[0]);
while ((opt = getopt(argc, argv, "rtbciesh?")) != -1) { while ((opt = getopt(argc, argv, "rtbciesvh?")) != -1) {
switch (opt) { switch (opt) {
case 'r': case 'r':
redraw = 1; redraw = 1;
@ -406,6 +434,10 @@ int main(int argc, char **argv)
reset = true; reset = true;
break; break;
case 'v':
visualize = true;
break;
default: default:
print_usage(prg); print_usage(prg);
exit(1); exit(1);