?? can_send.c
字號:
/* can driver* test programm* send messages commissioned via command line* * To do:* - more sequences for -t * - -debug schaltet mit debug level auch Treiber in debug mode* - ..* - do configuration of test with a special file format (can_send.rc)* - use nanosleep() see test3() ?** - CAN Errors are shown only in the basic mode.* use it in all test modes* and make an automatic reset in case of bus-off configurable** all activities has normally be finished before the progrmm can exit* and close the driver. Typiclyy the transmitt buffer is filled.* The programm has to wait for tx buffer empty before exiting.* At the momnt the program has some sleep() only.*/#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <stddef.h>#include <string.h>#include <signal.h>#include <sys/time.h>#include <time.h>#include <sys/ioctl.h>#include <math.h>#ifdef USE_RT_SCHEDULING# include <sched.h># include <sys/mman.h>#endif#include <errno.h>#include "can4linux.h"#if defined(EMBED)# if defined(COLDFIRE)/* IGW900 */# define STDDEV "/home/bin/can0"# else# define STDDEV "/dev/can0"# endif#else# define STDDEV "/dev/can1"#endif#define VERSION "1.9"#ifndef TRUE# define TRUE 1# define FALSE 0#endifextern int errno;canmsg_t message;void sbuf(unsigned char *s, int n);void usage(char *s);int can_fd;int node = 8;int debug = FALSE;int extd = FALSE;int load = 50; /* default bus-load */int doload = FALSE; /* default bus-load */int stresstest = FALSE;int testtype = 1; int sleeptime = 1; /* default: 1ms */int errwaittime = 1000; /* waittime after error */int cstdout = FALSE; /* use stdout for CAN message */long int test_count_soll = 1; /* single message */int rtr = FALSE;int baud = -1; /* dont change baud rate */int priority = -1; /* dont change priority rate */int canreset = FALSE;int endless = 0; /* endlees test *//* functions */void clean_process(void);void test1(void);void test2(void);void test3(void);void test10(void);void test11(void);void test12(void);void test20(void);void test30(void);void test31(void);void test40(void);/************************************************************************* set_bitrate - sets the CAN bit rate*** Changing these registers only possible in Reset mode.** RETURN:**/int set_bitrate( int fd, /* device descriptor */ int baud /* bit rate */ ){Config_par_t cfg;volatile Command_par_t cmd;int ret; cmd.cmd = CMD_STOP; ioctl(fd, CAN_IOCTL_COMMAND, &cmd); cfg.target = CONF_TIMING; cfg.val1 = baud; ret = ioctl(fd, CAN_IOCTL_CONFIG, &cfg); cmd.cmd = CMD_START; ioctl(fd, CAN_IOCTL_COMMAND, &cmd); if (ret < 0) { perror("set_bitrate"); exit(-1); } else { ret = 0; } return ret;}#include "getstat.c"int can_reset(void) {int ret;volatile Command_par_t cmd; cmd.cmd = CMD_RESET; ret = ioctl(can_fd, CAN_IOCTL_COMMAND, &cmd); return ret;}int can_start(void) {int ret;volatile Command_par_t cmd; cmd.cmd = CMD_CLEARBUFFERS; ret = ioctl(can_fd, CAN_IOCTL_COMMAND, &cmd); cmd.cmd = CMD_START; ret = ioctl(can_fd, CAN_IOCTL_COMMAND, &cmd); return ret;}void displayerror(canmsg_t *rx){/* static int boffcnt = 0; */ printf("Flags 0x%02x,", rx->flags); if( 0 == (rx->flags & MSG_ERR_MASK)) { printf(" CAN Error Free"); } if( rx->flags & MSG_WARNING) { printf(" CAN Warning Level,"); } if( rx->flags & MSG_PASSIVE) { printf(" CAN Error Passive,"); } if( rx->flags & MSG_BUSOFF) { printf(" CAN Bus Off,"); can_reset(); /* sleep 100ms */ usleep (100000); can_start(); } printf("\n");} /**** The main program**/int main(int argc, char **argv){int ret;int cnt;int c;char *pname;extern char *optarg;extern int optind;char device[40] = STDDEV;int max_priority;int increment = 0;long int test_count = 0; pname = *argv;#ifdef USE_RT_SCHEDULING max_priority = sched_get_priority_max(SCHED_RR) - 1;#else max_priority = 1;#endif /* our default 8 byte message */ message.id = 100; message.cob = 0; message.flags = 0; message.length = 8; message.data[0] = 0x55; message.data[1] = 2; message.data[2] = 3; message.data[3] = 4; message.data[4] = 5; message.data[5] = 6; message.data[6] = 7; message.data[7] = 0xaa; /* parse command line */ while ((c = getopt(argc, argv, "b:dehl:rp:s:n:D:t:T:VR")) != EOF) { switch (c) { case 'r': rtr = TRUE; break; case 'e': extd = TRUE; break; case 'b': baud = atoi(optarg); break; case 'l': load = atoi(optarg); doload = TRUE; break; case 'p': {#ifdef USE_RT_SCHEDULING struct sched_param mysched; priority = atoi(optarg); if (priority < 0 ) { fprintf(stderr, "Priority < 0 not allowed\n"); } if (priority > max_priority) { fprintf(stderr, "Priority > %d not allowed\n", max_priority); } mysched.sched_priority = sched_get_priority_max(SCHED_RR) - 1; ret = sched_setscheduler(0,SCHED_FIFO,&mysched); if ( debug == TRUE ) { printf("sched_setscheduler() = %d\n", ret); } /* lock all currently and in future allocated memory blocks in physical ram */ ret = mlockall(MCL_CURRENT | MCL_FUTURE); if ( debug == TRUE ) { printf("mlockall() = %d\n", ret); }#endif } break; case 's': sleeptime = atoi(optarg); endless |= 0x01; break; case 'n': node = atoi(optarg); sprintf(device, "/dev/canp%d", node); break; case 'D': if (0 == strcmp(optarg, "stdout")) { cstdout = TRUE; } else if ( /* path ist starting with '.' or '/', use it as it is */ optarg[0] == '.' || optarg[0] == '/' ) { sprintf(device, "%s", optarg); } else { sprintf(device, "/dev/%s", optarg); } break; case 'd': debug = TRUE; break; case 't': stresstest = TRUE; testtype = atoi(optarg); break; case 'T': test_count_soll = atoi(optarg); endless |= 0x02; break; case 'V': printf("can_send V " VERSION ", " __DATE__ "\n"); exit(0); break; case 'R': canreset = TRUE; break; case 'h': default: usage(pname); exit(0); } } /* look for additional arguments given on the command line */ if ( argc - optind > 0 ) { /* at least one additional argument, the message id is given */ message.id = strtol(argv[optind++], NULL, 0); memset(message.data, 0, 8); message.length = 0; } if ( argc - optind > 0 ) { /* also data bytes areg given with the command */ cnt = 0; while(optind != argc) { message.data[cnt++] = strtol(argv[optind++], NULL, 0); } message.length = cnt; } if (rtr) { message.flags |= MSG_RTR; } if (extd) { message.flags |= MSG_EXT; } if (endless != 0x01) { /* only the value 1 means endless, all other values means, * additional options used -> no endless */ endless = 0; } if ( debug == TRUE ) { printf("can_send V " VERSION ", " __DATE__ "\n"); printf("(c) 1996-2006 port GmbH\n"); printf(" using canmsg_t with %d bytes\n", sizeof(canmsg_t)); printf(" data at offset %d\n", offsetof(canmsg_t, data)); printf(" max process priority is \"-p %d\"\n", max_priority); if (stresstest) { printf("should send one of the test sequences\n"); } else { printf("should send mess %ld with: %s", message.id, message.length > 0 ? ": " : "out data"); sbuf(message.data, message.length); } } sleeptime *= 1000; if ( debug == TRUE ) { printf("Sleeptime between transmit messages= %d us\n", sleeptime); } srand(node * 100); if(sleeptime > 0) { errwaittime = sleeptime; } else { errwaittime = 1000; } if (cstdout == FALSE) { /* really use CAN, open the device driver */ if ( debug == TRUE ) { printf("Open device %s\n", device); } /* can_fd = open(device, O_WRONLY | O_NONBLOCK); */ can_fd = open(device, O_RDWR | O_NONBLOCK); if (can_fd == -1) { fprintf(stderr, "open error %d;", errno); perror(device); exit(1); } if ( canreset == TRUE ) { ret = can_reset(); if ( ret == -1 ) { perror("CAN Reset"); exit(EXIT_FAILURE); } if ( debug == TRUE) { printf("Reset successfull\n"); } exit(EXIT_SUCCESS); } if (baud > 0) { if ( debug == TRUE ) { printf("change Bit-Rate to %d Kbit/s\n", baud); } set_bitrate(can_fd, baud); } } else { can_fd = 1; /* use stdout */ } if ( debug == TRUE ) { printf("opened %s succesful, got can_fd = %d\n", device, can_fd); } if (doload == TRUE) { test20(); exit(0); } if (stresstest) { switch(testtype) { case 1: test1(); exit(0); break; case 2: test2(); exit(0); break; case 3: test3(); exit(0); break; case 4: increment = 1; break; case 10: test10(); exit(0); break; case 11: test11(); sleep(2); printf("finito\n"); exit(0); break; case 12: test12(); exit(0); break; case 30: test30(); exit(0); break; case 31: test31(); exit(0); break; case 40: test40(); exit(0); break; default: fprintf(stderr, "test type %d is not defined\n", testtype); exit(0); break; } } /* else */ /* the default can_send, simply send a message */ /* no special test, send the normal message, (old behaviouur) */ do { canmsg_t rx; int i; if(debug == TRUE) { printf(" transmit message %ld\n", message.id ); } ret = write(can_fd, &message, 1); if(ret == -1) { /* int e = errno; */ perror("write error"); /* if ( e == ENOSPC) { */ usleep(errwaittime); continue; /* } */ } else if(ret == 0) { printf("transmit timed out\n"); usleep(errwaittime); continue; } else { ; } /* now read the rx queue, it may contain * frames with id -1, which signals an error */ do { i = read(can_fd, &rx, 1); if(-1 == i) { perror("read error"); } else if((i > 0) && (CANDRIVERERROR == rx.id)) { displayerror(&rx); } } while(i > 0); if( debug == TRUE ) { showCANStat(can_fd); } if(sleeptime > 0) usleep(sleeptime); message.id += increment; test_count++; if(endless != 1) { if(test_count == test_count_soll) { break; } } } while(1); if (sleeptime == 0) { /* do not close while the controller is sending a message * sleep() then close() */ usleep(50000); /* sleep(1); */ } ret = close(can_fd); if (ret == -1) { fprintf(stderr, "close error %d;", errno); perror(""); exit(1); } if ( debug == TRUE ) { printf("closed fd = %d succesful\n", can_fd); } return 0;}/* show buffer in hex */void sbuf(unsigned char *s, int n){int i; for(i = 0; i< n; i++) { fprintf(stdout, "%02x ", *s++); }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -