Category Archives: Linux

Best of breed CAN device driver hitting mainline Linux Kernel 2.6.31

Starting with the upcoming 2.6.31 Linux Kernel (already available as 2.6.31-rc1) a functional version of the socketcan device driver found its way into mainline.

While socketcan itself has been in mainline for quite a while, there where no drivers for actual real-world hardware. This has now changed and I will therefore be able to run a Kernel which is one step closer to mainline.

Unfortunately however some kind of unioning filesystem is still missing.

Anyway, back to Controller–area network!

Since I wrote my own CAN device driver as a character device a couple of years ago I started thinking about a CAN-bus driver beeing implemented as a Network device. I wrote my own driver in the first place, because I needed concurrent access which is (needless to say) also possible with socketcan.

Fortunately two guys at Volkswagen Research finally started doing exactly this. Thank you to the socketcan people for providing such a nice piece of software!

So here is a mini HOWTO for getting it up and running.

What you need:

  • A GNU/Linux machine
  • A decent Kernel (2.6.31-rc1 or higher)
  • git and subversion
  • A supported CAN-bus card. I’m using one sold by EMS Wünsche, but a lot of other SJA1000 based cards may also work.
  • The simple userland utilities from svn://
  • A decent Version of iproute2 (not yet available in current GNU/Linux distributions at the time of writing)

How to get it up and running:

First of all compile and boot a Kernel where all CAN-related support is enabled either as a module or build into the Kernel.
Afterwords check out the userland utilities from subversion (svn checkout svn:// and compile them by just typing make.
Same goes for iproute2 (git clone git://; just type make as well. Copy all the resulting binaries to an appropriate place (e.g. /usr/local/bin). Do not use make install at least in iproute2 sourcetree, because this will replace your systems ip command.

Now all you need to do ist to enable you can0 interface by means of the following command:

ip link set can0 up txqueuelen 1000 type can bitrate 1000000

Use another value than 1000000 for different bitrates.

The txqueuelen might not be needed in your case if you don’t have peak traffic like I do.

OK, that`s it! You can now connect your bus to some device and use candump for watching your raw CAN pakets on the bus.

For integration into Debian GNU/Linux you may use something like the following in /etc/network/interfaces for automatically starting up your can0 device on system boot:

auto can0
iface can0 inet manual
# bitrate 1MBps
# increase TX queue length because of the pulsed nature of
# the traffic we generate
up /usr/local/bin/ip link set can0 up txqueuelen 1000 type can bitrate 1000000
down /sbin/ifconfig $IFACE down

See Documentation/networking/can.txt inside your Kernel tree for further documentation.

Effektiver Arbeiten auf der GNU bash

Wer mich kennt weiß, dass ich immer noch einen für manche vergleichsweise archaischen Desktop benutze. Streng nach dem alten Motto: Das X-Window System ist dafür da, dass man mehrere Konsolen nebeneinander benutzen kann.

Langer Rede kurzer Sinn, die aktuelle Version 4.0.x der Linux Standardshell hat nun zwei nette neue features, die ich natürlich gleich in meine .bashrc eingebaut habe.

Unterm Strich erspart man sich das häufige tippen der Kommandos cd und ssh.

Findet der Rechner einen unbekannten Befehl wird geschaut ob es ein Verzeichnis mit passendem Namen gibt, wenn ja wird in dieses Verzeichnis gewechselt. Wenn Nein wird nachgeschaut ob es einen passenden Rechnernamen gibt und wenn das der Fall ist erfolgt ein Remote Login über ssh auf diesem Rechner.

Das ganze sieht so aus:

# Auto-cd feature
shopt -s autocd

function command_not_found_handle() {
    host=$(echo $1 |sed -e 's/^.*@//g')
    # wenn hostname in .ssh/config, dann ssh dorthin
    if grep -q "Host $host" $HOME/.ssh/config; then
      ssh $*
      if ! getent hosts $host >/dev/null; then
        echo "bash: $*: Kommando nicht gefunden."
        ssh $*