/** \file canping.c Ping tool for round-trip measurement on CAN-bus. \author Cristiano Brudna \date 2003 University of Ulm, Germany This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #include #include "can.h" #define PING_ID 0x33 #define REPLY_ID 0x44 #define TIMEOUT_STANDARD_US 1 // 1s /* CAN-Bus */ int can; unsigned long baud_rate = B1000; /* round-trip */ int count = 0; int missedReplies = 0; int done; struct itimerval interval; long long timeout = TIMEOUT_STANDARD_US; int timeout_flag = 0; void printHelp(void) { printf("\nCAN Ping help\n\n"); printf("usage: ping [-r rounds] [-l length ] [-w maxwait] [-p] [-h] \n\n"); printf("-r rounds : set the number of round-trip measurements \n"); printf("-l length : set the number of data bytes to be sent in each message \n"); printf("-w maxwait : number of seconds to wait for a reply before sending a new message \n"); printf("-p : generate output for GNUplot \n"); printf("-h, --help : help\n"); printf("\n"); } void siginthandler(int egal) { done = 1; } /* SIGALRM handler (timer) */ void sigalrmHandler(int egal) { printf("Round-trip [%d] expired after %Lds \n", count, timeout); timeout_flag = 1; } int main(int argc, char **argv) { int ret, par; char opchr; canmsg ping_msg, reply_msg; int received; long int j; struct timeval send_time, receive_time; struct timezone tz; long long delay, min=9999999, max=0, sum=0; int rounds = 100, plot = 0; long long data[1000]; int length = 1; int pdelay = 50000; int help_flag; int option_index = 0; struct option long_options[] = { {"help", 0, &help_flag, 1}, {0, 0, 0, 0} }; while((opchr = getopt_long(argc, argv, "b:r:l:w:ph", long_options, &option_index)) != -1) switch(opchr) { case 'h': printHelp(); exit(0); case 'b': par = atoi(optarg); switch(par) { case 1000: baud_rate = B1000; break; case 500: baud_rate = B500; break; case 250: baud_rate = B250; break; case 125: baud_rate = B125; break; case 20: baud_rate = B20; break; default: printf("\nBaud rate not supported!!! Using 1Mbit/s instead\n"); } break; case 'r': rounds = atoi(optarg); break; case 'l': length = atoi(optarg); if(length < 1) length = 1; break; case 'w': timeout = atoi(optarg); // transform it into microseconds break; case 'p': plot = 1; break; default: break; } if(help_flag) { printHelp(); exit(0); } can = open("/dev/can", O_RDWR); if(can == -1) { perror("Error opening /dev/can"); exit(0); } ioctl(can, CAN_IOCSBAUD, &baud_rate); done = 0; signal(SIGINT, siginthandler); siginterrupt(SIGINT, 1); signal(SIGALRM, sigalrmHandler); siginterrupt(SIGALRM, 1); /* program the timer */ interval.it_value.tv_sec = timeout; interval.it_value.tv_usec = 0; while((count < rounds) && !done) { ping_msg.id = PING_ID; ping_msg.type = EXTENDED; ping_msg.len = length; for(j=0; j 0) && (reply_msg.id = REPLY_ID) ) { gettimeofday(&receive_time, &tz); // timestamp delay = (receive_time.tv_sec * 1000000 + receive_time.tv_usec) - (send_time.tv_sec * 1000000 + send_time.tv_usec); sum += delay; if(plot) { data[count] = delay; } else printf("Round-trip [%d] time = %Ldµs\n", count, delay); if(delay > max) max = delay; if(delay < min) min = delay; if(reply_msg.d[0] == (unsigned char)count) { received = 1; count++; } } } if(timeout_flag) { timeout_flag = 0; missedReplies++; data[count] = 0; count++; } usleep(pdelay); } if(plot) { printf("Results (min/avg/max) = %Ld / %Ld / %Ld µs\n", min, sum/count, max); for(j=0; j