rtcanconfig.c

00001 /*
00002  * Program to configuring the CAN controller
00003  *
00004  * Copyright (C) 2006 Wolfgang Grandegger <wg@grandegger.com>
00005  *
00006  * Copyright (C) 2005, 2006 Sebastian Smolorz
00007  *                          <Sebastian.Smolorz@stud.uni-hannover.de>
00008  *
00009  *
00010  * This program is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2 of the License, or
00013  * (at your option) any later version.
00014  *
00015  * This program is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * GNU General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU General Public License
00021  * along with this program; if not, write to the Free Software
00022  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
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     /* Get CAN interface name */
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) {   /* Get mode setting */
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 }

Generated on Mon Mar 24 18:02:40 2008 for Xenomai API by  doxygen 1.5.3