cansend: send multiple frames in one invocation
It is sometimes convenient to be able to send multiple frames with a single cansend invocation, otherwise the time between frames can get very large. Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>pull/93/head
parent
f811b53dfe
commit
b541771b7b
|
|
@ -11,7 +11,7 @@ subsystem (aka SocketCAN):
|
||||||
|
|
||||||
* candump : display, filter and log CAN data to files
|
* candump : display, filter and log CAN data to files
|
||||||
* canplayer : replay CAN logfiles
|
* canplayer : replay CAN logfiles
|
||||||
* cansend : send a single frame
|
* cansend : send single frames
|
||||||
* cangen : generate (random) CAN traffic
|
* cangen : generate (random) CAN traffic
|
||||||
* cansniffer : display CAN data content differences (just 11bit CAN IDs)
|
* cansniffer : display CAN data content differences (just 11bit CAN IDs)
|
||||||
|
|
||||||
|
|
|
||||||
94
cansend.c
94
cansend.c
|
|
@ -60,14 +60,15 @@ int main(int argc, char **argv)
|
||||||
int s; /* can raw socket */
|
int s; /* can raw socket */
|
||||||
int required_mtu;
|
int required_mtu;
|
||||||
int mtu;
|
int mtu;
|
||||||
int enable_canfd = 1;
|
int enable_canfd = 0;
|
||||||
|
int framecnt;
|
||||||
struct sockaddr_can addr;
|
struct sockaddr_can addr;
|
||||||
struct canfd_frame frame;
|
struct canfd_frame frame;
|
||||||
struct ifreq ifr;
|
struct ifreq ifr;
|
||||||
|
|
||||||
/* check command line options */
|
/* check command line options */
|
||||||
if (argc != 3) {
|
if (argc < 3) {
|
||||||
fprintf(stderr, "Usage: %s <device> <can_frame>.\n", argv[0]);
|
fprintf(stderr, "Usage: %s <device> <can_frame>...\n", argv[0]);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -100,52 +101,57 @@ int main(int argc, char **argv)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* parse CAN frame */
|
for (framecnt = 2; framecnt < argc; framecnt++) {
|
||||||
required_mtu = parse_canframe(argv[2], &frame);
|
/* parse CAN frame */
|
||||||
if (!required_mtu){
|
required_mtu = parse_canframe(argv[framecnt], &frame);
|
||||||
fprintf(stderr, "\nWrong CAN-frame format! Try:\n\n");
|
if (!required_mtu){
|
||||||
fprintf(stderr, " <can_id>#{R|data} for CAN 2.0 frames\n");
|
fprintf(stderr, "\nWrong CAN-frame format! Try:\n\n");
|
||||||
fprintf(stderr, " <can_id>##<flags>{data} for CAN FD frames\n\n");
|
fprintf(stderr, " <can_id>#{R|data} for CAN 2.0 frames\n");
|
||||||
fprintf(stderr, "<can_id> can have 3 (SFF) or 8 (EFF) hex chars\n");
|
fprintf(stderr, " <can_id>##<flags>{data} for CAN FD frames\n\n");
|
||||||
fprintf(stderr, "{data} has 0..8 (0..64 CAN FD) ASCII hex-values (optionally");
|
fprintf(stderr, "<can_id> can have 3 (SFF) or 8 (EFF) hex chars\n");
|
||||||
fprintf(stderr, " separated by '.')\n");
|
fprintf(stderr, "{data} has 0..8 (0..64 CAN FD) ASCII hex-values (optionally");
|
||||||
fprintf(stderr, "<flags> a single ASCII Hex value (0 .. F) which defines");
|
fprintf(stderr, " separated by '.')\n");
|
||||||
fprintf(stderr, " canfd_frame.flags\n\n");
|
fprintf(stderr, "<flags> a single ASCII Hex value (0 .. F) which defines");
|
||||||
fprintf(stderr, "e.g. 5A1#11.2233.44556677.88 / 123#DEADBEEF / 5AA# / ");
|
fprintf(stderr, " canfd_frame.flags\n\n");
|
||||||
fprintf(stderr, "123##1 / 213##311\n 1F334455#1122334455667788 / 123#R ");
|
fprintf(stderr, "e.g. 5A1#11.2233.44556677.88 / 123#DEADBEEF / 5AA# / ");
|
||||||
fprintf(stderr, "for remote transmission request.\n\n");
|
fprintf(stderr, "123##1 / 213##311\n 1F334455#1122334455667788 / 123#R ");
|
||||||
return 1;
|
fprintf(stderr, "for remote transmission request.\n\n");
|
||||||
}
|
|
||||||
|
|
||||||
if (required_mtu > CAN_MTU) {
|
|
||||||
|
|
||||||
/* check if the frame fits into the CAN netdevice */
|
|
||||||
if (ioctl(s, SIOCGIFMTU, &ifr) < 0) {
|
|
||||||
perror("SIOCGIFMTU");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
mtu = ifr.ifr_mtu;
|
|
||||||
|
|
||||||
if (mtu != CANFD_MTU) {
|
|
||||||
printf("CAN interface is not CAN FD capable - sorry.\n");
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* interface is ok - try to switch the socket into CAN FD mode */
|
if (required_mtu > CAN_MTU) {
|
||||||
if (setsockopt(s, SOL_CAN_RAW, CAN_RAW_FD_FRAMES,
|
|
||||||
&enable_canfd, sizeof(enable_canfd))){
|
if (enable_canfd == 0) {
|
||||||
printf("error when enabling CAN FD support\n");
|
/* check if the frame fits into the CAN netdevice */
|
||||||
return 1;
|
if (ioctl(s, SIOCGIFMTU, &ifr) < 0) {
|
||||||
|
perror("SIOCGIFMTU");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
mtu = ifr.ifr_mtu;
|
||||||
|
|
||||||
|
if (mtu != CANFD_MTU) {
|
||||||
|
printf("CAN interface is not CAN FD capable - sorry.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* interface is ok - try to switch the socket into CAN FD mode */
|
||||||
|
enable_canfd = 1;
|
||||||
|
if (setsockopt(s, SOL_CAN_RAW, CAN_RAW_FD_FRAMES,
|
||||||
|
&enable_canfd, sizeof(enable_canfd))){
|
||||||
|
printf("error when enabling CAN FD support\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ensure discrete CAN FD length values 0..8, 12, 16, 20, 24, 32, 64 */
|
||||||
|
frame.len = can_dlc2len(can_len2dlc(frame.len));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ensure discrete CAN FD length values 0..8, 12, 16, 20, 24, 32, 64 */
|
/* send frame */
|
||||||
frame.len = can_dlc2len(can_len2dlc(frame.len));
|
if (write(s, &frame, required_mtu) != required_mtu) {
|
||||||
}
|
perror("write");
|
||||||
|
return 1;
|
||||||
/* send frame */
|
}
|
||||||
if (write(s, &frame, required_mtu) != required_mtu) {
|
|
||||||
perror("write");
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
close(s);
|
close(s);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue