Skip to content

Commit 3615bac

Browse files
Merge pull request #301 from kurt-vd/canbusload-fd
[V2] canbusload with FD support
2 parents c1aae77 + 6382765 commit 3615bac

File tree

3 files changed

+54
-10
lines changed

3 files changed

+54
-10
lines changed

canbusload.c

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,11 @@ extern int optind, opterr, optopt;
7474
static struct {
7575
char devname[IFNAMSIZ+1];
7676
unsigned int bitrate;
77+
unsigned int dbitrate;
7778
unsigned int recv_frames;
7879
unsigned int recv_bits_total;
7980
unsigned int recv_bits_payload;
81+
unsigned int recv_bits_dbitrate;
8082
} stat[MAXSOCK+1];
8183

8284
static int max_devname_len; /* to prevent frazzled device name output */
@@ -103,7 +105,7 @@ void print_usage(char *prg)
103105
fprintf(stderr, " -e (exact calculation of stuffed bits)\n");
104106
fprintf(stderr, "\n");
105107
fprintf(stderr, "Up to %d CAN interfaces with mandatory bitrate can be specified on the \n", MAXSOCK);
106-
fprintf(stderr, "commandline in the form: <ifname>@<bitrate>\n\n");
108+
fprintf(stderr, "commandline in the form: <ifname>@<bitrate>[,<dbitrate>]\n\n");
107109
fprintf(stderr, "The bitrate is mandatory as it is needed to know the CAN bus bitrate to\n");
108110
fprintf(stderr, "calculate the bus load percentage based on the received CAN frames.\n");
109111
fprintf(stderr, "Due to the bitstuffing estimation the calculated busload may exceed 100%%.\n");
@@ -184,16 +186,18 @@ void printstats(int signo)
184186
}
185187

186188
if (stat[i].bitrate)
187-
percent = (stat[i].recv_bits_total*100)/stat[i].bitrate;
189+
percent = ((stat[i].recv_bits_total-stat[i].recv_bits_dbitrate) * 100) / stat[i].bitrate
190+
+ (stat[i].recv_bits_dbitrate * 100) / stat[i].dbitrate;
188191
else
189192
percent = 0;
190193

191-
printf(" %*s@%-*d %5d %7d %6d %3d%%",
194+
printf(" %*s@%-*d %5d %7d %6d %6d %3d%%",
192195
max_devname_len, stat[i].devname,
193196
max_bitrate_len, stat[i].bitrate,
194197
stat[i].recv_frames,
195198
stat[i].recv_bits_total,
196199
stat[i].recv_bits_payload,
200+
stat[i].recv_bits_dbitrate,
197201
percent);
198202

199203
if (bargraph) {
@@ -220,6 +224,7 @@ void printstats(int signo)
220224

221225
stat[i].recv_frames = 0;
222226
stat[i].recv_bits_total = 0;
227+
stat[i].recv_bits_dbitrate = 0;
223228
stat[i].recv_bits_payload = 0;
224229
}
225230

@@ -237,7 +242,7 @@ int main(int argc, char **argv)
237242
int opt;
238243
char *ptr, *nptr;
239244
struct sockaddr_can addr;
240-
struct can_frame frame;
245+
struct canfd_frame frame;
241246
int nbytes, i;
242247
struct ifreq ifr;
243248
sigset_t sigmask, savesigmask;
@@ -336,7 +341,13 @@ int main(int argc, char **argv)
336341
if (nbytes > max_devname_len)
337342
max_devname_len = nbytes; /* for nice printing */
338343

339-
stat[i].bitrate = atoi(nptr+1); /* bitrate is placed behind the '@' */
344+
char *endp;
345+
stat[i].bitrate = strtol(nptr + 1, &endp, 0); /* bitrate is placed behind the '@' */
346+
if (*endp == ',')
347+
/* data bitrate is placed behind the ',' */
348+
stat[i].dbitrate = strtol(endp + 1, &endp, 0);
349+
else
350+
stat[i].dbitrate = stat[i].bitrate;
340351

341352
if (!stat[i].bitrate || stat[i].bitrate > 1000000) {
342353
printf("invalid bitrate for CAN device '%s'!\n", ptr);
@@ -351,6 +362,9 @@ int main(int argc, char **argv)
351362
#ifdef DEBUG
352363
printf("using interface name '%s'.\n", ifr.ifr_name);
353364
#endif
365+
/* try to switch the socket into CAN FD mode */
366+
const int canfd_on = 1;
367+
setsockopt(s[i], SOL_CAN_RAW, CAN_RAW_FD_FRAMES, &canfd_on, sizeof(canfd_on));
354368

355369
if (ioctl(s[i], SIOCGIFINDEX, &ifr) < 0) {
356370
perror("SIOCGIFINDEX");
@@ -402,9 +416,11 @@ int main(int argc, char **argv)
402416
}
403417

404418
stat[i].recv_frames++;
405-
stat[i].recv_bits_payload += frame.can_dlc*8;
406-
stat[i].recv_bits_total += can_frame_length((struct canfd_frame*)&frame,
407-
mode, sizeof(frame));
419+
stat[i].recv_bits_payload += frame.len * 8;
420+
stat[i].recv_bits_dbitrate += can_frame_dbitrate_length(
421+
&frame, mode, sizeof(frame));
422+
stat[i].recv_bits_total += can_frame_length(&frame,
423+
mode, nbytes);
408424
}
409425
}
410426
}

canframelen.c

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -236,13 +236,40 @@ static unsigned cfl_exact(struct can_frame *frame)
236236
3; /* IFS */
237237
}
238238

239+
unsigned can_frame_dbitrate_length(struct canfd_frame *frame, enum cfl_mode mode, int mtu)
240+
{
241+
if (mtu != CANFD_MTU || !(frame->flags & CANFD_BRS))
242+
return 0;
243+
switch (mode) {
244+
case CFL_NO_BITSTUFFING:
245+
return 1 /* brs/crcdel */ + 1 /* esi */ + 4 /* dlc */ +
246+
((frame->len >= 16) ? 21 : 17) +
247+
frame->len * 8;
248+
case CFL_WORSTCASE:
249+
return can_frame_dbitrate_length(frame, CFL_NO_BITSTUFFING, mtu) * 5 / 4;
250+
default:
251+
return 0;
252+
}
253+
}
239254

240255
unsigned can_frame_length(struct canfd_frame *frame, enum cfl_mode mode, int mtu)
241256
{
242257
int eff = (frame->can_id & CAN_EFF_FLAG);
243258

244-
if (mtu != CAN_MTU)
245-
return 0; /* CANFD is not supported yet */
259+
if (mtu == CANFD_MTU)
260+
/* not correct, but close ? */
261+
switch (mode) {
262+
case CFL_NO_BITSTUFFING:
263+
return 1 + (eff ? 29 : 11) + ((frame->len >= 16) ? 21 : 17) +
264+
5 /* r1, ide, edl, r0, brs/crcdel, */ + 12 /* trail */ +
265+
frame->len * 8;
266+
case CFL_WORSTCASE:
267+
return can_frame_length(frame, CFL_NO_BITSTUFFING, mtu) * 5 / 4;
268+
case CFL_EXACT:
269+
return 0; /* exact bittiming for CANFD not supported yet */
270+
}
271+
else if (mtu != CAN_MTU)
272+
return 0; /* Only CAN2.0 and CANFD supported now */
246273

247274
switch (mode) {
248275
case CFL_NO_BITSTUFFING:

canframelen.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,5 +80,6 @@ enum cfl_mode {
8080
* Mode determines how to deal with stuffed bits.
8181
*/
8282
unsigned can_frame_length(struct canfd_frame *frame, enum cfl_mode mode, int mtu);
83+
unsigned can_frame_dbitrate_length(struct canfd_frame *frame, enum cfl_mode mode, int mtu);
8384

8485
#endif

0 commit comments

Comments
 (0)