Intro ===== Sllin is TTY discipline enabling you to create LIN Master (and partially LIN Slave) out of your computer. Hardware needed is Hardware UART embedded into the computer + simple voltage level LIN converter. Compilation =========== To successfully compile sllin, it is necessary to have source code of Linux kernel actually running on the computer. To compile, run $ make First steps =========== To use sllin, it is necessary to set sllin TTY discipline to some existing serial device. It is possible to use slightly modified slcan_attach program -- particular patch from canutils-patches folder has to be applied. After successful compilation and loading of sllin, patching and compiling of slcan_attach, it is possible to run: $ sudo slcan_attach -w /dev/ttyS0 attached tty /dev/ttyS0 to netdevice sllin0 Press any key to detach /dev/ttyS0 ... #It is also possible to use ldattach #$ sudo ldattach 25 /dev/ttyS0 #(To unattach, kill "ldattach") # Run from another terminal $ dmesg [157600.564071] sllin: sllin_kwthread stopped. [157600.572058] netconsole: network logging stopped, interface sllin0 unregistered [157608.437260] sllin: serial line LIN interface driver [157608.437267] sllin: 10 dynamic interface channels. [157608.437271] sllin: Break is generated manually with tiny sleep. [157610.513646] sllin: sllin_open() invoked [157610.519502] sllin: sllin_kwthread started. $ ip link show dev sllin0 11: sllin0: mtu 16 qdisc noop state DOWN qlen 10 link/can $ sudo ip link set sllin0 up $ ip link show dev sllin0 11: sllin0: mtu 16 qdisc pfifo_fast state UNKNOWN qlen 10 link/can # state UNKNOWN in this case is considered as wanted Real usage ========== Communication with sllin is done by sending different types of CAN frames into it. * EFF non-RTR frame: Configuration on internal "frame cache". * SFF RTR frame: Send LIN header with LIN ID corresponding to can_id in this particular CAN frame. * SFF non-RTR frame: Send LIN header immediately (with LIN ID corresponding to can_id in this particular CAN frame) followed by LIN response containing same data as this particular CAN frame. Module parameters ================= * maxdev -- Optional -- Possible values: unsigned int -- Maximum number of sllin interfaces. When not set, maxdev = 4. When maxdev < 4, maxdev = 4. * master -- Optional -- Possible values: 0 or 1 -- Sets if LIN interface will be in Master mode (1 = Master, 0 = Slave). When not set, master = 1. * baudrate -- Optional -- Possible values: unsigned int -- Baudrate used by LIN interface on LIN bus. When not set, baudrate = LIN_DEFAULT_BAUDRATE (19200). Examples ======== # Some outputs might be slightly modified for more comfortable reading $ ls sllin.c sllin.c $ make make -C /lib/modules/2.6.36.2-00398-g504e6a6-dirty/build M=/h.../sllin modules make[1]: Entering directory `/h.../kernel/build/glab-2.6.36' make -C /h.../kernel/2.6.36 O=/h.../kernel/build/glab-2.6.36/. modules ARCH=i386 CC [M] /h.../sllin/sllin.o Building modules, stage 2. MODPOST 1 modules LD [M] /h.../sllin/sllin.ko make[1]: Leaving directory `/h.../kernel/build/glab-2.6.36' $ sudo insmod ./sllin.ko $ dmesg | tail -3 [158268.949289] sllin: serial line LIN interface driver [158268.949296] sllin: 10 dynamic interface channels. [158268.949300] sllin: Break is generated manually with tiny sleep. # Run in another terminal $ sudo slcan_attach -w /dev/ttyS0 attached tty /dev/ttyS0 to netdevice sllin0 Press any key to detach /dev/ttyS0 ... $ sudo ip link set sllin0 up $ ip link show dev sllin0 12: sllin0: mtu 16 qdisc pfifo_fast state UNKNOWN qlen 10 link/can # Run "candump sllin0" in another terminal # ----- Simple RTR CAN frame ----- # Patched version of cangen $ cangen sllin0 -r -I 1 -n 1 -L 0 # Output from candump sllin0 1 [0] remote request sllin0 1 [2] 00 00 # First line: RTR sent to sllin0 # Second line: Response obtained from LIN bus (there was LIN slave # device on the LIN bus answering to LIN ID 1with data 0x00 0x00). # ----- RX_TIMEOUT ----- $ cangen sllin0 -r -I 8 -n 1 -L 0 # LIN_ERR_RX_TIMEOUT flag set -- nobody answered to our LIN header # or CAN RTR frame sllin0 8 [0] remote request sllin0 2000 [0] $ ip -s link show dev sllin0 14: sllin0: mtu 16 qdisc pfifo_fast state UNKNOWN qlen 10 link/can RX: bytes packets errors dropped overrun mcast 2 4 1 0 0 0 TX: bytes packets errors dropped carrier collsns 0 4 0 0 0 0 # ----- Configure frame cache ----- # Configure frame cache to answer on LIN ID = 8 $ cangen sllin0 -e -I 0x848 -n 1 -L 2 -D beef sllin0 848 [2] BE EF # Try RTR CAN frame with ID = 8 again $ cangen sllin0 -r -I 8 -n 1 -L 0 # Everything went better than expected sllin0 8 [0] remote request sllin0 8 [2] BE EF # ----- non-RTR CAN frame ----- $ cangen sllin0 -I 7 -n 1 -L 2 -D f00f sllin0 7 [2] F0 0F sllin0 7 [2] F0 0F # ----- Slave mode ----- $ insmod ./sllin.ko master=0 $ sudo slcan_attach -w /dev/ttyS0 attached tty /dev/ttyS0 to netdevice sllin0 Press any key to detach /dev/ttyS0 ... # run in another terminal $ sudo ip link set sllin0 up $ candump -t d sllin0 (000.000000) sllin0 2 [0] remote request (001.003734) sllin0 1 [0] remote request (000.000017) sllin0 1 [2] 08 80 (000.996027) sllin0 2 [0] remote request (001.003958) sllin0 1 [0] remote request (000.000017) sllin0 1 [2] 08 80 (000.996049) sllin0 2 [0] remote request (001.003930) sllin0 1 [0] remote request (000.000016) sllin0 1 [2] 08 80 (000.996053) sllin0 2 [0] remote request (001.003945) sllin0 1 [0] remote request (000.000017) sllin0 1 [2] 08 80 # There is one LIN header without response on the bus (= only RTR CAN frame) # and another LIN header followed by a response (= RTR + non-RTR CAN frame # with the same ID)