mirror of
https://github.com/linux-can/can-utils.git
synced 2026-09-21 15:29:56 +02:00
Compare commits
7
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3615bac17e | ||
|
|
6382765bf6 | ||
|
|
c1aae77740 | ||
|
|
37f316ebc3 | ||
|
|
e319afb10f | ||
|
|
e9a298ec21 | ||
|
|
e19b5abb5c |
@@ -273,6 +273,57 @@ static void printf_btr_rcar_can(struct can_bittiming *bt, bool hdr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void printf_btr_bxcan(struct can_bittiming *bt, bool hdr)
|
||||||
|
{
|
||||||
|
if (hdr) {
|
||||||
|
printf("%10s", "CAN_BTR");
|
||||||
|
} else {
|
||||||
|
uint32_t btr;
|
||||||
|
|
||||||
|
btr = (((bt->brp -1) & 0x3ff) << 0) |
|
||||||
|
(((bt->prop_seg + bt->phase_seg1 -1) & 0xf) << 16) |
|
||||||
|
(((bt->phase_seg2 -1) & 0x7) << 20) |
|
||||||
|
(((bt->sjw -1) & 0x3) << 24);
|
||||||
|
|
||||||
|
printf("0x%08x", btr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void printf_btr_c_can(struct can_bittiming *bt, bool hdr)
|
||||||
|
{
|
||||||
|
if (hdr) {
|
||||||
|
printf("%s", " BTR BRPEXT");
|
||||||
|
} else {
|
||||||
|
uint32_t btr;
|
||||||
|
uint32_t brpext;
|
||||||
|
|
||||||
|
btr = (((bt->brp -1) & 0x3f) << 0) |
|
||||||
|
(((bt->sjw -1) & 0x3) << 6) |
|
||||||
|
(((bt->prop_seg + bt->phase_seg1 -1) & 0xf) << 8) |
|
||||||
|
(((bt->phase_seg2 -1) & 0x7) << 12);
|
||||||
|
brpext = ((bt->brp -1) >> 6) & 0xf;
|
||||||
|
|
||||||
|
printf("0x%04x 0x%04x", btr, brpext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void printf_btr_mcan(struct can_bittiming *bt, bool hdr)
|
||||||
|
{
|
||||||
|
if (hdr) {
|
||||||
|
printf("%10s", "NBTP");
|
||||||
|
} else {
|
||||||
|
uint32_t nbtp;
|
||||||
|
|
||||||
|
|
||||||
|
nbtp = (((bt->brp -1) & 0x1ff) << 16) |
|
||||||
|
(((bt->sjw -1) & 0x7f) << 25) |
|
||||||
|
(((bt->prop_seg + bt->phase_seg1 -1) & 0xff) << 8) |
|
||||||
|
(((bt->phase_seg2 -1) & 0x7f) << 0);
|
||||||
|
|
||||||
|
printf("0x%08x", nbtp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static struct calc_bittiming_const can_calc_consts[] = {
|
static struct calc_bittiming_const can_calc_consts[] = {
|
||||||
{
|
{
|
||||||
.bittiming_const = {
|
.bittiming_const = {
|
||||||
@@ -417,6 +468,54 @@ static struct calc_bittiming_const can_calc_consts[] = {
|
|||||||
{ .clk = 65000000, },
|
{ .clk = 65000000, },
|
||||||
},
|
},
|
||||||
.printf_btr = printf_btr_rcar_can,
|
.printf_btr = printf_btr_rcar_can,
|
||||||
|
}, {
|
||||||
|
.bittiming_const = {
|
||||||
|
.name = "bxcan",
|
||||||
|
.tseg1_min = 1,
|
||||||
|
.tseg1_max = 16,
|
||||||
|
.tseg2_min = 1,
|
||||||
|
.tseg2_max = 8,
|
||||||
|
.sjw_max = 4,
|
||||||
|
.brp_min = 1,
|
||||||
|
.brp_max = 1024,
|
||||||
|
.brp_inc = 1,
|
||||||
|
},
|
||||||
|
.ref_clk = {
|
||||||
|
{ .clk = 48000000, },
|
||||||
|
},
|
||||||
|
.printf_btr = printf_btr_bxcan,
|
||||||
|
}, {
|
||||||
|
.bittiming_const = {
|
||||||
|
.name = "c_can",
|
||||||
|
.tseg1_min = 2,
|
||||||
|
.tseg1_max = 16,
|
||||||
|
.tseg2_min = 1,
|
||||||
|
.tseg2_max = 8,
|
||||||
|
.sjw_max = 4,
|
||||||
|
.brp_min = 1,
|
||||||
|
.brp_max = 1024,
|
||||||
|
.brp_inc = 1,
|
||||||
|
},
|
||||||
|
.ref_clk = {
|
||||||
|
{ .clk = 24000000, },
|
||||||
|
},
|
||||||
|
.printf_btr = printf_btr_c_can,
|
||||||
|
}, {
|
||||||
|
.bittiming_const = {
|
||||||
|
.name = "mcan-v3.1+",
|
||||||
|
.tseg1_min = 2,
|
||||||
|
.tseg1_max = 256,
|
||||||
|
.tseg2_min = 2,
|
||||||
|
.tseg2_max = 128,
|
||||||
|
.sjw_max = 128,
|
||||||
|
.brp_min = 1,
|
||||||
|
.brp_max = 512,
|
||||||
|
.brp_inc = 1,
|
||||||
|
},
|
||||||
|
.ref_clk = {
|
||||||
|
{ .clk = 40000000, },
|
||||||
|
},
|
||||||
|
.printf_btr = printf_btr_mcan,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+24
-8
@@ -74,9 +74,11 @@ extern int optind, opterr, optopt;
|
|||||||
static struct {
|
static struct {
|
||||||
char devname[IFNAMSIZ+1];
|
char devname[IFNAMSIZ+1];
|
||||||
unsigned int bitrate;
|
unsigned int bitrate;
|
||||||
|
unsigned int dbitrate;
|
||||||
unsigned int recv_frames;
|
unsigned int recv_frames;
|
||||||
unsigned int recv_bits_total;
|
unsigned int recv_bits_total;
|
||||||
unsigned int recv_bits_payload;
|
unsigned int recv_bits_payload;
|
||||||
|
unsigned int recv_bits_dbitrate;
|
||||||
} stat[MAXSOCK+1];
|
} stat[MAXSOCK+1];
|
||||||
|
|
||||||
static int max_devname_len; /* to prevent frazzled device name output */
|
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, " -e (exact calculation of stuffed bits)\n");
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
fprintf(stderr, "Up to %d CAN interfaces with mandatory bitrate can be specified on the \n", MAXSOCK);
|
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, "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, "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");
|
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)
|
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
|
else
|
||||||
percent = 0;
|
percent = 0;
|
||||||
|
|
||||||
printf(" %*s@%-*d %5d %7d %6d %3d%%",
|
printf(" %*s@%-*d %5d %7d %6d %6d %3d%%",
|
||||||
max_devname_len, stat[i].devname,
|
max_devname_len, stat[i].devname,
|
||||||
max_bitrate_len, stat[i].bitrate,
|
max_bitrate_len, stat[i].bitrate,
|
||||||
stat[i].recv_frames,
|
stat[i].recv_frames,
|
||||||
stat[i].recv_bits_total,
|
stat[i].recv_bits_total,
|
||||||
stat[i].recv_bits_payload,
|
stat[i].recv_bits_payload,
|
||||||
|
stat[i].recv_bits_dbitrate,
|
||||||
percent);
|
percent);
|
||||||
|
|
||||||
if (bargraph) {
|
if (bargraph) {
|
||||||
@@ -220,6 +224,7 @@ void printstats(int signo)
|
|||||||
|
|
||||||
stat[i].recv_frames = 0;
|
stat[i].recv_frames = 0;
|
||||||
stat[i].recv_bits_total = 0;
|
stat[i].recv_bits_total = 0;
|
||||||
|
stat[i].recv_bits_dbitrate = 0;
|
||||||
stat[i].recv_bits_payload = 0;
|
stat[i].recv_bits_payload = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -237,7 +242,7 @@ int main(int argc, char **argv)
|
|||||||
int opt;
|
int opt;
|
||||||
char *ptr, *nptr;
|
char *ptr, *nptr;
|
||||||
struct sockaddr_can addr;
|
struct sockaddr_can addr;
|
||||||
struct can_frame frame;
|
struct canfd_frame frame;
|
||||||
int nbytes, i;
|
int nbytes, i;
|
||||||
struct ifreq ifr;
|
struct ifreq ifr;
|
||||||
sigset_t sigmask, savesigmask;
|
sigset_t sigmask, savesigmask;
|
||||||
@@ -336,7 +341,13 @@ int main(int argc, char **argv)
|
|||||||
if (nbytes > max_devname_len)
|
if (nbytes > max_devname_len)
|
||||||
max_devname_len = nbytes; /* for nice printing */
|
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 == ',')
|
||||||
|
/* data bitrate is placed behind the ',' */
|
||||||
|
stat[i].dbitrate = strtol(endp + 1, &endp, 0);
|
||||||
|
else
|
||||||
|
stat[i].dbitrate = stat[i].bitrate;
|
||||||
|
|
||||||
if (!stat[i].bitrate || stat[i].bitrate > 1000000) {
|
if (!stat[i].bitrate || stat[i].bitrate > 1000000) {
|
||||||
printf("invalid bitrate for CAN device '%s'!\n", ptr);
|
printf("invalid bitrate for CAN device '%s'!\n", ptr);
|
||||||
@@ -351,6 +362,9 @@ int main(int argc, char **argv)
|
|||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("using interface name '%s'.\n", ifr.ifr_name);
|
printf("using interface name '%s'.\n", ifr.ifr_name);
|
||||||
#endif
|
#endif
|
||||||
|
/* try to switch the socket into CAN FD mode */
|
||||||
|
const int canfd_on = 1;
|
||||||
|
setsockopt(s[i], SOL_CAN_RAW, CAN_RAW_FD_FRAMES, &canfd_on, sizeof(canfd_on));
|
||||||
|
|
||||||
if (ioctl(s[i], SIOCGIFINDEX, &ifr) < 0) {
|
if (ioctl(s[i], SIOCGIFINDEX, &ifr) < 0) {
|
||||||
perror("SIOCGIFINDEX");
|
perror("SIOCGIFINDEX");
|
||||||
@@ -402,9 +416,11 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
stat[i].recv_frames++;
|
stat[i].recv_frames++;
|
||||||
stat[i].recv_bits_payload += frame.can_dlc*8;
|
stat[i].recv_bits_payload += frame.len * 8;
|
||||||
stat[i].recv_bits_total += can_frame_length((struct canfd_frame*)&frame,
|
stat[i].recv_bits_dbitrate += can_frame_dbitrate_length(
|
||||||
mode, sizeof(frame));
|
&frame, mode, sizeof(frame));
|
||||||
|
stat[i].recv_bits_total += can_frame_length(&frame,
|
||||||
|
mode, nbytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+29
-2
@@ -236,13 +236,40 @@ static unsigned cfl_exact(struct can_frame *frame)
|
|||||||
3; /* IFS */
|
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)
|
unsigned can_frame_length(struct canfd_frame *frame, enum cfl_mode mode, int mtu)
|
||||||
{
|
{
|
||||||
int eff = (frame->can_id & CAN_EFF_FLAG);
|
int eff = (frame->can_id & CAN_EFF_FLAG);
|
||||||
|
|
||||||
if (mtu != CAN_MTU)
|
if (mtu == CANFD_MTU)
|
||||||
return 0; /* CANFD is not supported yet */
|
/* 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; /* exact bittiming for CANFD not supported yet */
|
||||||
|
}
|
||||||
|
else if (mtu != CAN_MTU)
|
||||||
|
return 0; /* Only CAN2.0 and CANFD supported now */
|
||||||
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case CFL_NO_BITSTUFFING:
|
case CFL_NO_BITSTUFFING:
|
||||||
|
|||||||
@@ -80,5 +80,6 @@ enum cfl_mode {
|
|||||||
* Mode determines how to deal with stuffed bits.
|
* 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_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
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user