Signed-off-by: Kurt Van Dijck <dev.kurt@xxxxxxxxxxxxxxxxxxxxxx> --- canbusload.c | 20 ++++++++++++++++---- canframelen.c | 28 ++++++++++++++++++++++++++++ canframelen.h | 1 + 3 files changed, 45 insertions(+), 4 deletions(-) diff --git a/canbusload.c b/canbusload.c index bd74cb5..1bbfc72 100644 --- a/canbusload.c +++ b/canbusload.c @@ -74,9 +74,11 @@ extern int optind, opterr, optopt; static struct { char devname[IFNAMSIZ+1]; unsigned int bitrate; + unsigned int dbitrate; unsigned int recv_frames; unsigned int recv_bits_total; unsigned int recv_bits_payload; + unsigned int recv_bits_dbitrate; } stat[MAXSOCK+1]; static int max_devname_len; /* to prevent frazzled device name output */ @@ -103,7 +105,7 @@ void print_usage(char *prg) fprintf(stderr, " -e (exact calculation of stuffed bits)\n"); fprintf(stderr, "\n"); fprintf(stderr, "Up to %d CAN interfaces with mandatory bitrate can be specified on the \n", MAXSOCK); - fprintf(stderr, "commandline in the form: <ifname>@<bitrate>\n\n"); + fprintf(stderr, "commandline in the form: <ifname>@<bitrate>[,<dbitrate>]\n\n"); fprintf(stderr, "The bitrate is mandatory as it is needed to know the CAN bus bitrate to\n"); fprintf(stderr, "calculate the bus load percentage based on the received CAN frames.\n"); fprintf(stderr, "Due to the bitstuffing estimation the calculated busload may exceed 100%%.\n"); @@ -184,16 +186,18 @@ void printstats(int signo) } if (stat[i].bitrate) - percent = (stat[i].recv_bits_total*100)/stat[i].bitrate; + percent = ((stat[i].recv_bits_total-stat[i].recv_bits_dbitrate)*100)/stat[i].bitrate + + (stat[i].recv_bits_dbitrate*100)/stat[i].dbitrate; else percent = 0; - printf(" %*s@%-*d %5d %7d %6d %3d%%", + printf(" %*s@%-*d %5d %7d %6d %6d %3d%%", max_devname_len, stat[i].devname, max_bitrate_len, stat[i].bitrate, stat[i].recv_frames, stat[i].recv_bits_total, stat[i].recv_bits_payload, + stat[i].recv_bits_dbitrate, percent); if (bargraph) { @@ -220,6 +224,7 @@ void printstats(int signo) stat[i].recv_frames = 0; stat[i].recv_bits_total = 0; + stat[i].recv_bits_dbitrate = 0; stat[i].recv_bits_payload = 0; } @@ -336,7 +341,12 @@ int main(int argc, char **argv) if (nbytes > max_devname_len) max_devname_len = nbytes; /* for nice printing */ - stat[i].bitrate = atoi(nptr+1); /* bitrate is placed behind the '@' */ + char *endp; + stat[i].bitrate = strtol(nptr+1, &endp, 0); /* bitrate is placed behind the '@' */ + if (*endp == ',') + stat[i].dbitrate = strtol(endp+1, &endp, 0); /* bitrate is placed behind the ',' */ + else + stat[i].dbitrate = stat[i].bitrate; if (!stat[i].bitrate || stat[i].bitrate > 1000000) { printf("invalid bitrate for CAN device '%s'!\n", ptr); @@ -406,6 +416,8 @@ int main(int argc, char **argv) stat[i].recv_frames++; stat[i].recv_bits_payload += frame.len*8; + stat[i].recv_bits_dbitrate += can_frame_dbitrate_length( + &frame, mode, sizeof(frame)); stat[i].recv_bits_total += can_frame_length(&frame, mode, nbytes); } diff --git a/canframelen.c b/canframelen.c index b708691..1a3584a 100644 --- a/canframelen.c +++ b/canframelen.c @@ -236,11 +236,39 @@ static unsigned cfl_exact(struct can_frame *frame) 3; /* IFS */ } +unsigned can_frame_dbitrate_length(struct canfd_frame *frame, enum cfl_mode mode, int mtu) +{ + if (mtu != CANFD_MTU || !(frame->flags & CANFD_BRS)) + return 0; + switch (mode) { + case CFL_NO_BITSTUFFING: + return 1 /* brs/crcdel */ + 1 /* esi */ + 4 /* dlc */ + + ((frame->len >= 16) ? 21 : 17) + + frame->len*8; + case CFL_WORSTCASE: + return can_frame_dbitrate_length(frame, CFL_NO_BITSTUFFING, mtu) * 5 / 4; + default: + return 0; + } +} unsigned can_frame_length(struct canfd_frame *frame, enum cfl_mode mode, int mtu) { int eff = (frame->can_id & CAN_EFF_FLAG); + if (mtu == CANFD_MTU) + /* not correct, but close ? */ + switch (mode) { + case CFL_NO_BITSTUFFING: + return 1+(eff ? 29 : 11) + ((frame->len >= 16) ? 21 : 17) + + + 5 /* r1, ide, edl, r0, brs/crcdel, */ + 12 /* trail */ + + frame->len*8; + case CFL_WORSTCASE: + return can_frame_length(frame, CFL_NO_BITSTUFFING, mtu) * 5 / 4; + case CFL_EXACT: + return 0; /* CANFD is not supported yet */ + } + else if (mtu != CAN_MTU) return 0; /* CANFD is not supported yet */ diff --git a/canframelen.h b/canframelen.h index 641119d..47739b2 100644 --- a/canframelen.h +++ b/canframelen.h @@ -80,5 +80,6 @@ enum cfl_mode { * Mode determines how to deal with stuffed bits. */ unsigned can_frame_length(struct canfd_frame *frame, enum cfl_mode mode, int mtu); +unsigned can_frame_dbitrate_length(struct canfd_frame *frame, enum cfl_mode mode, int mtu); #endif -- 2.25.0