]> rtime.felk.cvut.cz Git - linux-lin.git/commitdiff
linconf: Basic sllin configuration.
authorRostislav Lisovy <lisovy@gmail.com>
Wed, 18 Jul 2012 15:33:05 +0000 (17:33 +0200)
committerRostislav Lisovy <lisovy@gmail.com>
Wed, 18 Jul 2012 15:33:05 +0000 (17:33 +0200)
lin_config/src/Makefile
lin_config/src/lin_config.c
lin_config/src/lin_config.h
lin_config/src/pcl_config.c
lin_config/src/pcl_config.h
lin_config/src/sllin_config.c [new file with mode: 0644]

index bd91ff7830a449495fbaebf1897323a0933b4b1d..52b7c2d10dd3066fe563ad5c87755dd07662ff08 100644 (file)
@@ -3,7 +3,7 @@ CFLAGS=-std=gnu99 -Wall -pedantic $(DEBUG) `xml2-config --cflags`
 LIBS=`xml2-config --libs`
 DEBUG=-ggdb
 
-objects = linc_parse_xml.o pcl_config.o lin_config.o
+objects = linc_parse_xml.o pcl_config.o sllin_config.o lin_config.o
 
 lin_config: $(objects)
        $(CC) $(objects) $(LIBS) -o lin_config
index 9dcad11de283fbc56b65e02174a44b8ffb92518f..891494c7325bc8018e6f672ebea4bf9adc335686 100644 (file)
 #include <assert.h>
 #include "linc_parse_xml.h"
 #include "pcl_config.h"
+#include "sllin_config.h"
 #include "lin_config.h"
 
 
 void linc_explain(int argc, char *argv[])
 {
+// FIXME what is default behaviour
+// Write a warning about not using a rs232--usb converter for sllin
        fprintf(stderr, "Usage: %s [OPTIONS] <SERIAL_INTERFACE>\n", argv[0]);
        fprintf(stderr, "\n");
-       fprintf(stderr, "'pcan_lin_config' Is used for configuring PEAK PCAN-LIN device.\n");
-       fprintf(stderr, "  When invoked without any OPTIONS, it configures PCAN-LIN device\n");
-       fprintf(stderr, "  with configuration obtained from '"PCL_DEFAULT_CONFIG"' file (if it exists).\n");
-       fprintf(stderr, "  The PCAN-LIN module enables CAN, LIN and serial participants to communicate.\n");
+       fprintf(stderr, "'lin_config' is used for configuring sllin -- " \
+               "simple LIN device implemented\n" \
+               "  as a TTY line discipline for arbitrary UART interface.\n" \
+               "  This program is able to configure PCAN-LIN (RS232 configurable " \
+               "LIN node) as well.\n" \
+               "  When invoked without any OPTIONS, it configures PCAN-LIN device\n" \
+               "  with configuration obtained from '"PCL_DEFAULT_CONFIG"' " \
+               "file (if it exists).\n");
        fprintf(stderr, "\n");
-       fprintf(stderr, "Options:\n");
+       fprintf(stderr, "SERIAL_INTERFACE is in format CLASS:PATH\n");
+       fprintf(stderr, "  CLASS defines the device class -- it is either " \
+               "'sllin' or 'pcanlin'\n");
+       fprintf(stderr, "  PATH is path to the serial interface, e.g /dev/ttyS0\n");
+       fprintf(stderr, "\n");
+       fprintf(stderr, "General options:\n");
+       fprintf(stderr, " -c <FILE>   Path to XML configuration file in PCLIN format\n");
        fprintf(stderr, " -r          Execute only Reset of a device\n");
-       fprintf(stderr, " -f          Flash the active configuration\n");
-       fprintf(stderr, " -c <FILE>   Path to XML configuration file\n");
+       fprintf(stderr, "\n");
+       fprintf(stderr, "PCAN-LIN specific options:\n");
+       fprintf(stderr, " -f          Store the active configuration into internal " \
+               "flash memory\n");
+       fprintf(stderr, "\n");
+       fprintf(stderr, "Sllin specific options:\n");
+       fprintf(stderr, " -a          Attach sllin TTY line discipline to " \
+               "particular SERIAL_INTERFACE\n");
+       fprintf(stderr, " -d          Detach sllin TTY line discipline from " \
+               "particular SERIAL_INTERFACE\n");
        fprintf(stderr, "\n");
        fprintf(stderr, "Examples:\n");
-       fprintf(stderr, " %s /dev/ttyS0      (Configure the device with the configuration from '"PCL_DEFAULT_CONFIG"')\n",
-               argv[0]);
-       fprintf(stderr, " %s -r /dev/ttyS0   (Reset the device)\n", argv[0]);
+       fprintf(stderr, " %s sllin:/dev/ttyS0        (Configure the device with the " \
+               "configuration from '"PCL_DEFAULT_CONFIG"')\n", argv[0]);
+       fprintf(stderr, " %s -r pcanlin:/dev/ttyS0   (Reset the device)\n", argv[0]);
 }
 
 int main(int argc, char *argv[])
@@ -57,7 +78,7 @@ int main(int argc, char *argv[])
        int flags = 0;
        char *filename = NULL;
 
-       while ((opt = getopt(argc, argv, "rfc:")) != -1) {
+       while ((opt = getopt(argc, argv, "rfc:ad")) != -1) {
                switch (opt) {
                case 'r':
                        flags |= RESET_DEVICE_fl;
@@ -68,9 +89,15 @@ int main(int argc, char *argv[])
                case 'c':
                        filename = optarg;
                        break;
+               case 'a':
+                       flags |= SLLIN_ATTACH_fl;
+                       break;
+               case 'd':
+                       flags |= SLLIN_DETACH_fl;
+                       break;
                default:
                        linc_explain(argc, argv);
-                       exit(EXIT_FAILURE);
+                       return EXIT_FAILURE;
                }
        }
 
@@ -86,7 +113,16 @@ int main(int argc, char *argv[])
        if (!ret)
                printf("Configuration file %s parsed correctly\n", filename);
 
-       pcl_config(&linc_lin_state, flags);
+       linc_lin_state.flags = flags;
+       //ret = pcl_config(&linc_lin_state);
+       ret = sllin_config(&linc_lin_state);
+
+//     printf("Press any key to detach %s ...\n", linc_lin_state.dev);
+//     getchar();
+
+
+       if (ret < 0)
+               return EXIT_FAILURE;
 
        return EXIT_SUCCESS;
 }
index 9bf6d0098679ada37d983e60e47cc847f92fe45d..e46cf8af19bf1249cf66340082c3683943c1df16 100644 (file)
@@ -3,6 +3,8 @@
 
 #define FLASH_CONF_fl                          (1 << 0)
 #define RESET_DEVICE_fl                                (1 << 1)
+#define SLLIN_ATTACH_fl                                (1 << 2)
+#define SLLIN_DETACH_fl                                (1 << 3)
 
 #define MAX_LIN_ID                             0x3F
 #define PCL_DEFAULT_CONFIG                     "config.pclin"
@@ -20,16 +22,21 @@ struct linc_frame_entry {
 };
 
 struct linc_lin_state {
-       int is_active;
-       int baudrate;
-       int master_status;
-       int bus_termination;
+       int is_active;          /* Is LIN device active */
+       int baudrate;           /* LIN baudrate */
+       int master_status;      /* LIN node type -- Master or Slave */
+       int bus_termination;    /* LIN bus termination in device -- Master or Slave */
 
+       /* Subscriber/publisher table entries */
        struct linc_frame_entry frame_entry[MAX_LIN_ID];
-       struct linc_scheduler_entry scheduler_entry[100]; // FIXME max value
-       int scheduler_entries_cnt;
-
-       char *dev;
+       /* Scheduler table entries */
+       // FIXME max value
+       struct linc_scheduler_entry scheduler_entry[100];
+       int scheduler_entries_cnt; /* No. of configured scheduler entries */
+
+       char *dev;              /* Path to LIN device to be configured */
+       int flags;              /* Flags passed to configuration function
+                               of particular device */
 };
 struct linc_lin_state linc_lin_state;
 
index 61e07e281263d12ba6631302fbc57588f3fd03e3..06c60044527eb4de8b6cc195e22b10bfc890198c 100644 (file)
@@ -420,7 +420,7 @@ int pcl_lin_init(int tty, struct linc_lin_state *linc_lin_state)
        return 0;
 }
 
-int pcl_config(struct linc_lin_state *linc_lin_state, unsigned int flags)
+int pcl_config(struct linc_lin_state *linc_lin_state)
 {
        int tty;
 
@@ -433,22 +433,24 @@ int pcl_config(struct linc_lin_state *linc_lin_state, unsigned int flags)
        pcl_set_input_mode(tty);
 
 
-       if (flags & RESET_DEVICE_fl) {
+       if (linc_lin_state->flags & RESET_DEVICE_fl) {
                pcl_reset_device(tty);
                        return 0;
        }
 
        pcl_lin_init(tty, linc_lin_state);
 
-       if (flags & FLASH_CONF_fl) {
+       if (linc_lin_state->flags & FLASH_CONF_fl) {
                pcl_flash_config(tty);
                pcl_reset_device(tty);
        }
 
+       // FIXME add warning on unrecognized flags
+       //if (flags & (RESET_DEVICE_fl | FLASH_CONF_fl))
+
        pcl_reset_input_mode(tty);
        close(tty);
 
        return 0;
 }
 
-
index 0b8deeec64c828a625f3e0f795826c1206e05195..70b1b16e4e217b7dd1ddf577943eff237837b334 100644 (file)
@@ -37,6 +37,6 @@ typedef struct {
        uint8_t chks;       /* Checksum; Bitwise XOR of all bytes except STX */
 } pcl_packet_t;
 
-int pcl_config(struct linc_lin_state *linc_lin_state, unsigned int flags);
+int pcl_config(struct linc_lin_state *linc_lin_state);
 
 #endif /* _PCL_CONFIG_H_ */
diff --git a/lin_config/src/sllin_config.c b/lin_config/src/sllin_config.c
new file mode 100644 (file)
index 0000000..f2c24fa
--- /dev/null
@@ -0,0 +1,144 @@
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/uio.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <linux/can.h>
+#include <linux/can/bcm.h>
+
+#include "lin_config.h"
+
+#define SLLIN_LDISC                                    25
+struct bcm_msg {
+       struct bcm_msg_head msg_head;
+       struct can_frame frame;
+};
+
+struct sllin_connection {
+       int bcm_sock; // FIXME is necessary??
+       int can_sock;
+       char iface[IFNAMSIZ+1];
+};
+
+int sllin_bcm_config(struct linc_lin_state *linc_lin_state,
+                       struct sllin_connection *sllin_connection)
+{
+       struct sockaddr_can caddr;
+       struct ifreq ifr;
+       struct bcm_msg msg;
+       int s;
+       int ret;
+       int i;
+
+       //printf("tty %s to netdevice %s\n", linc_lin_state->dev, sllin_connection->iface);
+
+       s = socket(PF_CAN, SOCK_DGRAM, CAN_BCM);
+       if (s < 0) {
+               perror("socket(): bcmsocket");
+               return -1;
+       }
+
+       strcpy(ifr.ifr_name, sllin_connection->iface);
+       ioctl(s, SIOCGIFINDEX, &ifr);
+
+       memset(&caddr, 0, sizeof(caddr));
+       caddr.can_family = AF_CAN;
+       caddr.can_ifindex = ifr.ifr_ifindex;
+
+//     ret = bind(s, (struct sockaddr*)&caddr, sizeof(caddr));
+//     if (ret < 0) {
+//             perror("bind()");
+//             return -1;
+//     }
+//
+//     sllin_connection->bcm_sock = s;
+
+       ret = connect(s, (struct sockaddr *)&caddr, sizeof(caddr));
+       if (ret < 0) {
+               perror("connect()");
+               return -1;
+       }
+
+       for (i = 0; i < linc_lin_state->scheduler_entries_cnt; i++) {
+               memset(&msg, 0, sizeof(msg));
+               msg.msg_head.nframes = 1;
+               msg.msg_head.opcode = TX_SETUP;
+               msg.msg_head.flags |= SETTIMER | STARTTIMER;
+               //msg.msg_head.ival2.tv_sec =  // FIXME
+               msg.msg_head.ival2.tv_usec =
+                       linc_lin_state->scheduler_entry[i].interval_ms * 1000;
+               msg.msg_head.can_id =
+                       linc_lin_state->scheduler_entry[i].lin_id | CAN_RTR_FLAG;
+               msg.frame.can_dlc = 0;
+
+               sendto(s, &msg, sizeof(msg), 0,
+                       (struct sockaddr*)&caddr, sizeof(caddr));
+               printf(".\n");
+               //read_response(s); // FIXME
+       }
+
+       close(s);
+
+       printf("Configuration finished\n");
+       return 0;
+}
+
+int sllin_config(struct linc_lin_state *linc_lin_state)
+{
+       int tty;
+       int ldisc = SLLIN_LDISC;
+       int ret;
+       struct sllin_connection sllin_connection;
+
+       tty = open(linc_lin_state->dev, O_WRONLY | O_NOCTTY);
+       if (tty < 0) {
+               perror("open()");
+               return -1;
+       }
+
+       /* Set sllin line discipline on given tty */
+       if (linc_lin_state->flags & SLLIN_ATTACH_fl) {
+               ret = ioctl(tty, TIOCSETD, &ldisc);
+               if (ret < 0) {
+                       perror("ioctl TIOCSETD");
+                       return -1;
+               }
+
+               /* Retrieve the name of the created CAN netdevice */
+               ret = ioctl(tty, SIOCGIFNAME, sllin_connection.iface);
+               if (ret < 0) {
+                       perror("ioctl SIOCGIFNAME");
+                       return -1;
+               }
+
+               printf("Attached tty %s to netdevice %s\n", linc_lin_state->dev, sllin_connection.iface);
+       }
+
+       if (linc_lin_state->flags & SLLIN_DETACH_fl) {
+               ldisc = N_TTY;
+               ret = ioctl(tty, TIOCSETD, &ldisc);
+               if (ret < 0) {
+                       perror("ioctl");
+                       return -1;
+               }
+
+               printf("Detached sllin line discipline from %s\n", linc_lin_state->dev);
+               return 0;
+       }
+
+       ret = sllin_bcm_config(linc_lin_state, &sllin_connection);
+
+       printf("Press any key to detach %s ...\n", linc_lin_state->dev);
+       getchar();
+       close(tty);
+       return ret;
+}
+