00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <stdio.h>
00026 #include <stdlib.h>
00027 #include <signal.h>
00028 #include <unistd.h>
00029 #include <string.h>
00030 #include <time.h>
00031 #include <errno.h>
00032 #include <getopt.h>
00033 #include <sys/mman.h>
00034
00035 #include <rtdm/rtcan.h>
00036
00037 static void print_usage(char *prg)
00038 {
00039 fprintf(stderr,
00040 "Usage: %s <can-interface> [Options] [up|down|start|stop|sleep]\n"
00041 "Options:\n"
00042 " -v, --verbose be verbose\n"
00043 " -h, --help this help\n"
00044 " -c, --ctrlmode=CTRLMODE listenonly, loopback or none\n"
00045 " -b, --baudrate=BPS baudrate in bits/sec\n"
00046 " -B, --bittime=BTR0:BTR1 BTR or standard bit-time\n"
00047 " -B, --bittime=BRP:PROP_SEG:PHASE_SEG1:PHASE_SEG2:SJW:SAM\n",
00048 prg);
00049 }
00050
00051 can_baudrate_t string_to_baudrate(char *str)
00052 {
00053 can_baudrate_t baudrate;
00054 if (sscanf(str, "%i", &baudrate) != 1)
00055 return -1;
00056 return baudrate;
00057 }
00058
00059 int string_to_mode(char *str)
00060 {
00061 if ( !strcmp(str, "up") || !strcmp(str, "start") )
00062 return CAN_MODE_START;
00063 else if ( !strcmp(str, "down") || !strcmp(str, "stop") )
00064 return CAN_MODE_STOP;
00065 else if ( !strcmp(str, "sleep") )
00066 return CAN_MODE_SLEEP;
00067 return -EINVAL;
00068 }
00069
00070 int string_to_ctrlmode(char *str)
00071 {
00072 if ( !strcmp(str, "listenonly") )
00073 return CAN_CTRLMODE_LISTENONLY;
00074 else if ( !strcmp(str, "loopback") )
00075 return CAN_CTRLMODE_LOOPBACK;
00076 else if ( !strcmp(str, "none") )
00077 return 0;
00078
00079 return -1;
00080 }
00081
00082 int main(int argc, char *argv[])
00083 {
00084 char ifname[16];
00085 int can_fd = -1;
00086 int new_baudrate = -1;
00087 int new_mode = -1;
00088 int new_ctrlmode = 0, set_ctrlmode = 0;
00089 int verbose = 0;
00090 int bittime_count = 0, bittime_data[6];
00091 struct ifreq ifr;
00092 can_baudrate_t *baudrate;
00093 can_ctrlmode_t *ctrlmode;
00094 can_mode_t *mode;
00095 struct can_bittime *bittime;
00096 int opt, ret;
00097 char* ptr;
00098
00099 struct option long_options[] = {
00100 { "help", no_argument, 0, 'h' },
00101 { "verbose", no_argument, 0, 'v'},
00102 { "baudrate", required_argument, 0, 'b'},
00103 { "bittime", required_argument, 0, 'B'},
00104 { "ctrlmode", required_argument, 0, 'c'},
00105 { 0, 0, 0, 0},
00106 };
00107
00108 while ((opt = getopt_long(argc, argv, "hvb:B:c:",
00109 long_options, NULL)) != -1) {
00110 switch (opt) {
00111 case 'h':
00112 print_usage(argv[0]);
00113 exit(0);
00114
00115 case 'v':
00116 verbose = 1;
00117 break;
00118
00119 case 'b':
00120 new_baudrate = string_to_baudrate(optarg);
00121 if (new_baudrate == -1) {
00122 print_usage(argv[0]);
00123 exit(0);
00124 }
00125 break;
00126
00127 case 'B':
00128 ptr = optarg;
00129 while (1) {
00130 bittime_data[bittime_count++] = strtoul(ptr, NULL, 0);
00131 if (!(ptr = strchr(ptr, ':')))
00132 break;
00133 ptr++;
00134 }
00135 if (bittime_count != 2 && bittime_count != 6) {
00136 print_usage(argv[0]);
00137 exit(0);
00138 }
00139 break;
00140
00141 case 'c':
00142 ret = string_to_ctrlmode(optarg);
00143 if (ret == -1) {
00144 print_usage(argv[0]);
00145 exit(0);
00146 }
00147 new_ctrlmode |= ret;
00148 set_ctrlmode = 1;
00149 break;
00150
00151 break;
00152
00153 default:
00154 fprintf(stderr, "Unknown option %c\n", opt);
00155 break;
00156 }
00157 }
00158
00159
00160 if (optind != argc - 1 && optind != argc - 2) {
00161 print_usage(argv[0]);
00162 return 0;
00163 }
00164
00165 strncpy(ifname, argv[optind], IFNAMSIZ);
00166 strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
00167
00168 if (optind == argc - 2) {
00169 new_mode = string_to_mode(argv[optind + 1]);
00170 if (verbose)
00171 printf("mode: %s (%#x)\n", argv[optind + 1], new_mode);
00172 if (new_mode < 0) {
00173 print_usage(argv[0]);
00174 return 0;
00175 }
00176 }
00177
00178 can_fd = rt_dev_socket(PF_CAN, SOCK_RAW, CAN_RAW);
00179 if (can_fd < 0) {
00180 fprintf(stderr, "Cannot open RTDM CAN socket. Maybe driver not loaded? \n");
00181 return can_fd;
00182 }
00183
00184 ret = rt_dev_ioctl(can_fd, SIOCGIFINDEX, &ifr);
00185 if (ret) {
00186 fprintf(stderr,"Can't get interface index for %s, code = %d\n", ifname, ret);
00187 return ret;
00188 }
00189
00190
00191 if (new_baudrate != -1) {
00192 if (verbose)
00193 printf("baudrate: %d\n", new_baudrate);
00194 baudrate = (can_baudrate_t *)&ifr.ifr_ifru;
00195 *baudrate = new_baudrate;
00196 ret = rt_dev_ioctl(can_fd, SIOCSCANBAUDRATE, &ifr);
00197 if (ret) {
00198 goto abort;
00199 }
00200 }
00201
00202 if (bittime_count) {
00203 bittime = (struct can_bittime *)&ifr.ifr_ifru;
00204 if (bittime_count == 2) {
00205 bittime->type = CAN_BITTIME_BTR;
00206 bittime->btr.btr0 = bittime_data[0];
00207 bittime->btr.btr1 = bittime_data[1];
00208 if (verbose)
00209 printf("bit-time: btr0=0x%02x btr1=0x%02x\n",
00210 bittime->btr.btr0, bittime->btr.btr1);
00211 } else {
00212 bittime->type = CAN_BITTIME_STD;
00213 bittime->std.brp = bittime_data[0];
00214 bittime->std.prop_seg = bittime_data[1];
00215 bittime->std.phase_seg1 = bittime_data[2];
00216 bittime->std.phase_seg2 = bittime_data[3];
00217 bittime->std.sjw = bittime_data[4];
00218 bittime->std.sam = bittime_data[5];
00219 if (verbose)
00220 printf("bit-time: brp=%d prop_seg=%d phase_seg1=%d "
00221 "phase_seg2=%d sjw=%d sam=%d\n",
00222 bittime->std.brp,
00223 bittime->std.prop_seg,
00224 bittime->std.phase_seg1,
00225 bittime->std.phase_seg2,
00226 bittime->std.sjw,
00227 bittime->std.sam);
00228 }
00229
00230 ret = rt_dev_ioctl(can_fd, SIOCSCANCUSTOMBITTIME, &ifr);
00231 if (ret) {
00232 goto abort;
00233 }
00234
00235 }
00236
00237 if (set_ctrlmode != 0) {
00238 ctrlmode = (can_ctrlmode_t *)&ifr.ifr_ifru;
00239 *ctrlmode = new_ctrlmode;
00240 if (verbose)
00241 printf("ctrlmode: %#x\n", new_ctrlmode);
00242 ret = rt_dev_ioctl(can_fd, SIOCSCANCTRLMODE, &ifr);
00243 if (ret) {
00244 goto abort;
00245 }
00246 }
00247
00248 if (new_mode != -1) {
00249 mode = (can_mode_t *)&ifr.ifr_ifru;
00250 *mode = new_mode;
00251 ret = rt_dev_ioctl(can_fd, SIOCSCANMODE, &ifr);
00252 if (ret) {
00253 goto abort;
00254 }
00255 }
00256
00257 rt_dev_close(can_fd);
00258 return 0;
00259
00260 abort:
00261 rt_dev_close(can_fd);
00262 return ret;
00263 }