Samstag, 15. August 2015

Step-by-step guide: Installing the Lawicel CANUSB adapter on Linux

This tutorial explains how to get the Lawicel CANUSB device running and automatically loaded when it’s plugged in. You’ll need access to an operating CAN network with at least one sending node to test. Other CAN interfaces may work as well, as long as they’re using „slcan“ (interfaces not using "slcan" are set up very different from what you'll read here). Tested on Ubuntu 14.04. If you want to run it on a Raspberry Pi, note that you need to use the Raspberry Pi 2, since the RPi1 doesn’t support Ubuntu. Using Raspbian would also be possible, but requires compiling the kernel including the slcan drivers (which means a lot of work).

Follow the following steps carefully:


1. Install the „can-utils“ package (which includes the required slcan daemon):
sudo apt-get install can-utils

2. Check if the kernel modules „can“, „can_raw“ and „slcan“ are already loaded:
lsmod
If not, load them manually:
sudo modprobe can
sudo modprobe can_raw
sudo modprobe slcan
If modprobe says „Module not found“ at this point, your linux distribution is missing the can modules. If modprobe says nothing, the modules exist. Now let’s make them load automatically:
sudo nano /etc/modules
Add the three modules „can“, „can_raw“, „slcan“ to the list (each goes in one line).

3. Connect the CANUSB to the CAN network, plug it into the USB port and check if it shows up:
lsusb
It should be listed as „Future Technology Devices International, Ltd FT232 USB-Serial (UART) IC“. Also check that it shows up as device „ttyUSBX“ (in most cases „ttyUSB0“):
ls /dev
If it doesn’t show up, install the FTDI VCP drivers (see http://www.ftdichip.com).

4. Now we will bind the CANUSB device to the slcan interface:
The following table contains all possible CAN bus speed settings:
sX
CAN speed
s0
10 Kbit/s
s1
20 Kbit/s
s2
50 Kbit/s
s3
100 Kbit/s
s4
125 Kbit/s
s5
250 Kbit/s
s6
500 Kbit/s
s7
800 Kbit/s
s8
1000 Kbit/s
Bind the interface (replace the parameters –sX and ttyUSBX with the correct values):
sudo slcand -o -c -f -sX /dev/ttyUSBX slcan0
Now check that the interface has been added successfully (the following command should list „slcan0“ in state „DOWN“):
ip addr
If it’s not in the list, check the system log file for errors:
sudo tail -n 10 -f /var/log/syslog

5. Bring the slcan interface up:
sudo ifconfig slcan0 up
Before proceeding, check the interface state – it should’ve changed from „DOWN“ to „UNKNOWN“:
ip addr

6. Now check for CAN messages (make sure at least one CAN node is sending):
candump slcan0
You should see CAN messages now. If not, check the green LED (it should light up whenever a CAN message is received). Also make sure you chose the correct CAN bus speed setting and the CAN bus has at least one active sending node. Exit the program using CTRL+C.

7. Now we will automate the linking process (steps 3 to 5) so the system will perform it whenever we plug in the CANUSB interface. First create a new udev rule:
sudo nano /etc/udev/rules.d/90-slcan.rules
Add the following content:
# Lawicel CANUSB module
ACTION=="add", ENV{ID_MODEL}=="CANUSB", ENV{SUBSYSTEM}=="tty", RUN+="/usr/bin/logger [udev] Lawicel CANUSB detected - running slcan_add.sh!", RUN+="/usr/local/bin/slcan_add.sh $kernel"
ACTION=="remove", ENV{ID_MODEL}=="CANUSB", ENV{SUBSYSTEM}=="usb", RUN+="/usr/bin/logger [udev] Lawicel CANUSB removed - running slcan_remove.sh!", RUN+="/usr/local/bin/slcan_remove.sh"
Make sure that you removed the line breaks (each ACTION command needs to be in it’s own line).

8. Create the script that will be called by udev when CANUSB is plugged in:
sudo nano /usr/local/bin/slcan_add.sh
Add the following content:
#!/bin/sh
# Bind the USBCAN device
slcand -o -c -f -sX /dev/$1 slcan0
sleep 2
ifconfig slcan0 up 
Reminder: Fill in the -sX parameter to suit your CAN bus speed!

9. Create the script that will be called by udev when CANUSB is removed:
sudo nano /usr/local/bin/slcan_remove.sh
Add the following content:
#!/bin/sh
# Remove the USBCAN device
pkill slcand

10. Make both scripts executable:
sudo chmod +x /usr/local/bin/slcan_add.sh
sudo chmod +x /usr/local/bin/slcan_remove.sh
Now remove the CANUSB from the USB port.

11. Reboot to make udev apply the new rule:
sudo reboot
Plug the CANUSB back in.

12. Check slcan for functionality again:
candump slcan0
If it doesn’t work, check the system log for errors and use the udev monitor for hints:
sudo tail -n 10 -f /var/log/syslog
udevadm monitor --property

Done! From now on the Lawicel CANUSB interface can be plugged in and out at any time and it should set up automatically.
  
Trivia:
- The Lawicel CANUSB interface uses the FTDI Serial-to-USB chip, which comes with two drivers: The D2XX (direct device access) and the VCP (ascii based virtual com port), which we use.
- Newer linux distributions have the required SocketCAN kernel modules included. There are 3 types available: Native CAN („can“), virtual CAN („vcan“) and serial CAN („slcan“). Since we are using the VCP driver, we are using slcan.
- The green LED on the CANUSB indicates that CAN frames have been received or sent (they’re only working if the correct CAN bus speed has been set). The red LED shows if the module is in errornous state – to fix, clear the error bit by software (or replug and reboot).

Kommentare:

  1. Nice summary, thanks for providing it! Great help to get started with CANUSB in a Linux environment. Best regards, Oliver

    AntwortenLöschen
  2. Great tutorial. It is working fine except the automatic plug. In the syslog you can see that everything is OK, but the daemon avahi is making trouble:

    raspberrypi avahi-daemon[426]: Withdrawing workstation service for slcan0

    Any idea to solve this ?
    Cheers Dirk

    AntwortenLöschen
    Antworten
    1. Thanks! Sorry I never used avahi, but this sounds more like a note to me. Since it wouldn't make sense for avahi to add a can-interface, it just ignores that interface. To make that hint disappear, i think you need to open the avari configuration file (i.e. /etc/avahi/avahi-daemon.conf) and add "slcan0" to the line "deny-interfaces=".

      Löschen
    2. It is the NetworkManager killing the can device.
      NetworkManager[604]: devices removed (path: /sys/devices/virtual/net/slcan0, iface: slcan0

      None of the tips found across the internet seem to work. I found the following:

      Change slcan_add.sh to contain:
      echo "/usr/local/bin/slcan_defer.sh $1" | /usr/bin/batch

      then put the former content of slcan_add.sh in a new script slcan_defer.sh. Don't forget to make this one executable too.

      Some other changes I made:
      - modprobe can_raw first. It will pull the module can itself.
      - In the udev script, changed ENV{ID_MODEL}=="CANUSB" to ENV{ID_MODEL_ID}=="6001". Then it will work with other devices based on the same chip, not only Lawicel.

      Löschen
    3. Oh thanks for this tip about the network manager interferring. Worked for me after installing batch through 'apt install at'.

      Löschen
  3. thanks for that can bus speed table. you have no idea how long i've been searching for that

    AntwortenLöschen
  4. Sorry for the typo previously...

    When the CANUSB is detected as ttyUSB1, it shall be bind as slcan1. I guess socketcan binds ttyUSBx to slcanx. How shall I modify the script for this? Thanks!

    AntwortenLöschen
    Antworten
    1. The binding process of ttyUSBx to slcanx is not made by socketcan automatically. You have to do it on your own (see step 4). If the CANUSB on your machine is detected as ttyUSB1, and you want the can interface name to be slcan1, the command would be:
      sudo slcand -o -c -f -sX /dev/ttyUSB1 slcan1
      Note: You may also name the can interface "donald_trump" instead of "slcan1". It's up to you :-)
      Note2: Don't forget to replace parameter "-sX" by the according speed parameter from the table (see step 4).

      Löschen
  5. Hi,

    I want to install virtual can driver interface (vcan0) in one of my ARM device. When i give modprobe vcan the responce is : module vcan not found. So can any one suggest where exactly i get the kernel object vcan fro my ARM device

    AntwortenLöschen
    Antworten
    1. I'm sorry, as a linux beginner I can't help you on this. :-(

      Löschen
  6. Hi,
    I followed your steps, but i m not able to read the data in termninal after giving command as "candump slcan0"
    Please help me with this.

    AntwortenLöschen
    Antworten
    1. Assuming that you didn't get any error from candump, this could cause the trouble:
      1. The wrong bus speed has been set (see #4).
      2. There is no activity on the CAN bus.
      3. The CAN bus is not terminated properly (this is very important, even if you only connect to one single CAN node).

      You may also try opening up another console, and use the tool "cansend" to send some data. You should immediately see it on candump.

      Löschen
  7. Der Kommentar wurde von einem Blog-Administrator entfernt.

    AntwortenLöschen
  8. Hello!
    These are great instructions, and I got them to work no problem on my laptop that has Ubuntu 16.04 LTS. I can effectively send CAN frames to the device I wish, and it behaves as expected.

    However, my next step was to put this on a raspberry pi. I have a raspberry pi 3, and loaded ubuntu-mate (version 16.04.1 LTS) onto it. That went well, but when I try to add the slcan module in step 2, I get a 'fatal' error saying that the module cannot be found. Any idea why this is occurring? Why would I need to compile the kernel with the slcan drivers if I am using Ubuntu? Thanks!

    AntwortenLöschen
    Antworten
    1. Hi, sorry but I'm not very much into linux. As the intro of this tutorial says, I tested all this using Ubuntu 14.04. I can't tell what has been changed since then. Sorry :-(

      Löschen