/** \file analyser.c * * CANBus Message Analyser * * \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 #include #include "can.h" #include "canlib.h" #define LIST_SIZE 40 /* text format */ char *BLACK = "\033[30m", *RED = "\033[31m", *GREEN = "\033[32m", *YELLOW = "\033[33m", *BLUE = "\033[34m", *MAGENTA = "\033[35m", *CYAN = "\033[36m", *WHITE = "\033[37m", *RESET = "\033[m", *BOLD = "\033[1m", *ITALIC = "\033[3m", *UNDERLINE = "\033[4m", *INVERSE = "\033[7m", *CROSSEDPOUT = "\033[9m"; int can; ///< file descriptor of the can device int done = 0; ///< struct itimerval interval; ///< timer used to update the results long long sample = 1; ///< standard sample time (1s) typedef struct { CanId id; ///< identifier of the CAN message int counter; ///< number of messages received during the current sample time long totalCount; ///< message counter since start float averageRate; ///< average rate of the message in messages/second } msg_entry; int listSize = LIST_SIZE; ///< maximum size of the list int listTail = 0; ///< current size of the list msg_entry msgList[LIST_SIZE]; ///< List of analysed messages struct termios old, new_termios; void siginthandler (int a) { done = 1; } unsigned long long timevalToUs (struct timeval time) { return ((unsigned long long)time.tv_sec*1000000 + (unsigned long long)time.tv_usec); } void set_noecho() { tcgetattr(0, &old); new_termios = old; new_termios.c_lflag &= ~(ICANON | ECHO | ECHONL); tcsetattr(0, TCSANOW, &new_termios); } void set_echo() { tcsetattr(0, TCSANOW, &old); } int findEntry (canmsg *canMsg) { int i; for(i=0; iid) return i; } return -1; } int createEntry (canmsg *canMsg) { int i; for(i=0; iid) return -1; /* the entry already exists */ } msgList[listTail].id = canMsg->id; msgList[listTail].counter = 0; msgList[listTail].totalCount = 0; msgList[listTail].averageRate = 0; listTail++; return (listTail-1); /* OK */ } void resetCounters (void) { int i; for(i=0; i 0) { index = findEntry(&msg); if(index == -1) { index = createEntry(&msg); } if(index != -1) { msgList[index].counter++; msgList[index].totalCount++; } } } } int main (int argc, char *argv[]) { unsigned long baudrate = B1000; long long acode = -1, amask = -1; char opchr; int par; setupterm( 0, 2, 0 ); while((opchr = getopt(argc,argv, "hb:m:c:s:")) != -1) switch(opchr) { case 'h': printf("\nCAN Analyser help\n\n"); printf("usage: cansend [-b baud] [-m mask] [-c code] [-h] \n\n"); printf("-b baud : set baudrate [1000, 500, 250, 125, 20] kbit/s\n"); printf("-m amask : set a 32-bit acceptance mask\n"); printf("-c acode : set a 32-bit acceptance code\n"); printf("-s sample time : set the period of time is seconds used to calculate/update the bus load\n"); printf("-h : help\n"); printf("\n"); exit(0); case 'b': par = atoi(optarg); switch(par) { case 1000: baudrate = B1000; break; case 500: baudrate = B500; break; case 250: baudrate = B250; break; case 125: baudrate = B125; break; case 20: baudrate = B20; break; default: printf("\nBaud rate not supported!!! Using 1Mbit/s instead\n"); } break; case 'm': sscanf(optarg, "%Lx", (long long *) &amask); /* printf("amask = %Lx\n", amask); */ break; case 'c': sscanf(optarg, "%Lx", (long long *) &acode); /* printf("acode = %Lx\n", acode); */ break; case 's': sscanf(optarg, "%Lx", (long long *) &sample); /* printf("sample = %Lxs \n", sample); */ break; default: break; } can = open("/dev/can", O_RDWR); if(can == -1) { perror("Error opening /dev/can"); exit(0); } ioctl(can, CAN_IOCSBAUD, &baudrate); if(acode != -1) { ioctl(can, CAN_IOCSACODE, &acode); } if(amask != -1) { ioctl(can, CAN_IOCSAMASK, &amask); } signal(SIGINT, siginthandler); siginterrupt(SIGINT, 1); signal(SIGALRM, showBusLoad); siginterrupt(SIGALRM, 1); /* program the timer */ interval.it_value.tv_sec = sample; interval.it_value.tv_usec = 0; setitimer(ITIMER_REAL, &interval, NULL); monitor(); close(can); return 0; }