Xenomai  3.1
rtcanconfig.c
/*
* Program to configuring the CAN controller
*
* Copyright (C) 2006 Wolfgang Grandegger <wg@grandegger.com>
*
* Copyright (C) 2005, 2006 Sebastian Smolorz
* <Sebastian.Smolorz@stud.uni-hannover.de>
*
*
* 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 <boilerplate/ancillaries.h>
#include <rtdm/can.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);
}
static can_baudrate_t string_to_baudrate(char *str)
{
can_baudrate_t baudrate;
if (sscanf(str, "%i", &baudrate) != 1)
return -1;
return baudrate;
}
static int string_to_mode(char *str)
{
if ( !strcmp(str, "up") || !strcmp(str, "start") )
else if ( !strcmp(str, "down") || !strcmp(str, "stop") )
return CAN_MODE_STOP;
else if ( !strcmp(str, "sleep") )
return -EINVAL;
}
static int string_to_ctrlmode(char *str)
{
if ( !strcmp(str, "listenonly") )
else if ( !strcmp(str, "loopback") )
else if ( !strcmp(str, "none") )
return 0;
return -1;
}
int main(int argc, char *argv[])
{
char ifname[IFNAMSIZ];
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 can_ifreq ifr;
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;
}
namecpy(ifname, argv[optind]);
namecpy(ifr.ifr_name, ifname);
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 = 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 = ioctl(can_fd, SIOCGIFINDEX, &ifr);
if (ret) {
fprintf(stderr,"Can't get interface index for %s, errno = %d\n", ifname, errno);
return ret;
}
if (new_baudrate != -1) {
if (verbose)
printf("baudrate: %d\n", new_baudrate);
ifr.ifr_ifru.baudrate = new_baudrate;
ret = ioctl(can_fd, SIOCSCANBAUDRATE, &ifr);
if (ret) {
goto abort;
}
}
if (bittime_count) {
bittime = &ifr.ifr_ifru.bittime;
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 = ioctl(can_fd, SIOCSCANCUSTOMBITTIME, &ifr);
if (ret) {
goto abort;
}
}
if (set_ctrlmode != 0) {
ifr.ifr_ifru.ctrlmode = new_ctrlmode;
if (verbose)
printf("ctrlmode: %#x\n", new_ctrlmode);
ret = ioctl(can_fd, SIOCSCANCTRLMODE, &ifr);
if (ret) {
goto abort;
}
}
if (new_mode != -1) {
ifr.ifr_ifru.mode = new_mode;
ret = ioctl(can_fd, SIOCSCANMODE, &ifr);
if (ret) {
goto abort;
}
}
close(can_fd);
return 0;
abort:
close(can_fd);
return ret;
}