Xenomai API
2.5.6.1
|
/* * Program to configuring the CAN controller * * Copyright (C) 2006 Wolfgang Grandegger <[email protected]> * * Copyright (C) 2005, 2006 Sebastian Smolorz * <[email protected]> * * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <stdio.h> #include <stdlib.h> #include <signal.h> #include <unistd.h> #include <string.h> #include <time.h> #include <errno.h> #include <getopt.h> #include <sys/mman.h> #include <rtdm/rtcan.h> static void print_usage(char *prg) { fprintf(stderr, "Usage: %s <can-interface> [Options] [up|down|start|stop|sleep]\n" "Options:\n" " -v, --verbose be verbose\n" " -h, --help this help\n" " -c, --ctrlmode=CTRLMODE listenonly, loopback or none\n" " -b, --baudrate=BPS baudrate in bits/sec\n" " -B, --bittime=BTR0:BTR1 BTR or standard bit-time\n" " -B, --bittime=BRP:PROP_SEG:PHASE_SEG1:PHASE_SEG2:SJW:SAM\n", prg); } can_baudrate_t string_to_baudrate(char *str) { can_baudrate_t baudrate; if (sscanf(str, "%i", &baudrate) != 1) return -1; return baudrate; } int string_to_mode(char *str) { if ( !strcmp(str, "up") || !strcmp(str, "start") ) return CAN_MODE_START; else if ( !strcmp(str, "down") || !strcmp(str, "stop") ) return CAN_MODE_STOP; else if ( !strcmp(str, "sleep") ) return CAN_MODE_SLEEP; return -EINVAL; } int string_to_ctrlmode(char *str) { if ( !strcmp(str, "listenonly") ) return CAN_CTRLMODE_LISTENONLY; else if ( !strcmp(str, "loopback") ) return CAN_CTRLMODE_LOOPBACK; else if ( !strcmp(str, "none") ) return 0; return -1; } int main(int argc, char *argv[]) { char ifname[16]; int can_fd = -1; int new_baudrate = -1; int new_mode = -1; int new_ctrlmode = 0, set_ctrlmode = 0; int verbose = 0; int bittime_count = 0, bittime_data[6]; struct ifreq ifr; can_baudrate_t *baudrate; can_ctrlmode_t *ctrlmode; can_mode_t *mode; struct can_bittime *bittime; int opt, ret; char* ptr; struct option long_options[] = { { "help", no_argument, 0, 'h' }, { "verbose", no_argument, 0, 'v'}, { "baudrate", required_argument, 0, 'b'}, { "bittime", required_argument, 0, 'B'}, { "ctrlmode", required_argument, 0, 'c'}, { 0, 0, 0, 0}, }; while ((opt = getopt_long(argc, argv, "hvb:B:c:", long_options, NULL)) != -1) { switch (opt) { case 'h': print_usage(argv[0]); exit(0); case 'v': verbose = 1; break; case 'b': new_baudrate = string_to_baudrate(optarg); if (new_baudrate == -1) { print_usage(argv[0]); exit(0); } break; case 'B': ptr = optarg; while (1) { bittime_data[bittime_count++] = strtoul(ptr, NULL, 0); if (!(ptr = strchr(ptr, ':'))) break; ptr++; } if (bittime_count != 2 && bittime_count != 6) { print_usage(argv[0]); exit(0); } break; case 'c': ret = string_to_ctrlmode(optarg); if (ret == -1) { print_usage(argv[0]); exit(0); } new_ctrlmode |= ret; set_ctrlmode = 1; break; break; default: fprintf(stderr, "Unknown option %c\n", opt); break; } } /* Get CAN interface name */ if (optind != argc - 1 && optind != argc - 2) { print_usage(argv[0]); return 0; } strncpy(ifname, argv[optind], IFNAMSIZ); strncpy(ifr.ifr_name, ifname, IFNAMSIZ); if (optind == argc - 2) { /* Get mode setting */ new_mode = string_to_mode(argv[optind + 1]); if (verbose) printf("mode: %s (%#x)\n", argv[optind + 1], new_mode); if (new_mode < 0) { print_usage(argv[0]); return 0; } } can_fd = rt_dev_socket(PF_CAN, SOCK_RAW, CAN_RAW); if (can_fd < 0) { fprintf(stderr, "Cannot open RTDM CAN socket. Maybe driver not loaded? \n"); return can_fd; } ret = rt_dev_ioctl(can_fd, SIOCGIFINDEX, &ifr); if (ret) { fprintf(stderr,"Can't get interface index for %s, code = %d\n", ifname, ret); return ret; } if (new_baudrate != -1) { if (verbose) printf("baudrate: %d\n", new_baudrate); baudrate = (can_baudrate_t *)&ifr.ifr_ifru; *baudrate = new_baudrate; ret = rt_dev_ioctl(can_fd, SIOCSCANBAUDRATE, &ifr); if (ret) { goto abort; } } if (bittime_count) { bittime = (struct can_bittime *)&ifr.ifr_ifru; if (bittime_count == 2) { bittime->type = CAN_BITTIME_BTR; bittime->btr.btr0 = bittime_data[0]; bittime->btr.btr1 = bittime_data[1]; if (verbose) printf("bit-time: btr0=0x%02x btr1=0x%02x\n", bittime->btr.btr0, bittime->btr.btr1); } else { bittime->type = CAN_BITTIME_STD; bittime->std.brp = bittime_data[0]; bittime->std.prop_seg = bittime_data[1]; bittime->std.phase_seg1 = bittime_data[2]; bittime->std.phase_seg2 = bittime_data[3]; bittime->std.sjw = bittime_data[4]; bittime->std.sam = bittime_data[5]; if (verbose) printf("bit-time: brp=%d prop_seg=%d phase_seg1=%d " "phase_seg2=%d sjw=%d sam=%d\n", bittime->std.brp, bittime->std.prop_seg, bittime->std.phase_seg1, bittime->std.phase_seg2, bittime->std.sjw, bittime->std.sam); } ret = rt_dev_ioctl(can_fd, SIOCSCANCUSTOMBITTIME, &ifr); if (ret) { goto abort; } } if (set_ctrlmode != 0) { ctrlmode = (can_ctrlmode_t *)&ifr.ifr_ifru; *ctrlmode = new_ctrlmode; if (verbose) printf("ctrlmode: %#x\n", new_ctrlmode); ret = rt_dev_ioctl(can_fd, SIOCSCANCTRLMODE, &ifr); if (ret) { goto abort; } } if (new_mode != -1) { mode = (can_mode_t *)&ifr.ifr_ifru; *mode = new_mode; ret = rt_dev_ioctl(can_fd, SIOCSCANMODE, &ifr); if (ret) { goto abort; } } rt_dev_close(can_fd); return 0; abort: rt_dev_close(can_fd); return ret; }