linuxdebianlinux-device-drivercan-bussocketcan

Debian: Module can-dev loaded with load-modules.conf does not work until I reload it manually


I have a slight problem with using can bus on a raspberry pi with Debian 64 bit running on it.

My /etc/modules-load.d/modules.conf looks like this:

# /etc/modules: kernel modules to load at boot time.
#
# This file contains the names of kernel modules that should be loaded
# at boot time, one per line. Lines beginning with "#" are ignored.
ixxat_usb2can
can-dev
can-raw

Right after startup and sshing to the machine, I have the modules loaded:

~/$ lsmod | grep can
can_raw                28672  0
can                    28672  1 can_raw
ixxat_usb2can          28672  0
can_dev                28672  1 ixxat_usb2can
usbcore               266240  5 xhci_hcd,ixxat_usb2can,dwc2,brcmfmac,xhci_pci

The can bus seems to be ready and the interface can0 is up:

~/$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether e4:5f:01:2e:2e:72 brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.77/24 brd 192.168.0.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 2a02:810b:43c0:539c:e65f:1ff:fe2e:2e72/64 scope global dynamic mngtmpaddr
       valid_lft 86398sec preferred_lft 43198sec
    inet6 fe80::e65f:1ff:fe2e:2e72/64 scope link
       valid_lft forever preferred_lft forever
3: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UP group default qlen 10
    link/can
4: can1: <NOARP,ECHO> mtu 16 qdisc noop state DOWN group default qlen 10
    link/can
5: wlan0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether e4:5f:01:2e:2e:73 brd ff:ff:ff:ff:ff:ff
6: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
    link/ether 02:42:6b:e0:11:18 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever

if I try to access a motor device connected via can adapter on interface can0, it does not work, I get an error code from the motor control library which is, sadly, not documented, but it happens while trying to find the can device.

What I think is weird: I only need to reload the can-dev module to make it work. Afterwards, there is no change to lsmod, but I can find the device and the motor moves just as I wish to:

~/$ sudo /sbin/modprobe can-dev
~/$ lsmod | grep can
can_raw                28672  0
can                    28672  1 can_raw
ixxat_usb2can          28672  0
can_dev                28672  1 ixxat_usb2can
usbcore               266240  5 xhci_hcd,ixxat_usb2can,dwc2,brcmfmac,xhci_pci

So my basic question is: What happens here? Am I missing anything? Thanks in advance!


Solution

  • I just figured it out, kind of, so in case someone runs into any problem like this:

    I have never looked at interface can1, because I don't use it. My usb to can dongle has this interface, but it is open ended, nothing is connected there, so it was way out of my scope. But having a closer look at ip a right after start and then again after loading the can-dev-module a second time manually reveals that it has impact on the state of interface can1.

    Before manually loading can-dev:

    3: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UP group default qlen 10
        link/can
    4: can1: <NOARP,ECHO> mtu 16 qdisc noop state DOWN group default qlen 10
        link/can
    

    and afterwards:

    3: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UP group default qlen 10
        link/can
    4: can1: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UP group default qlen 10
        link/can
    

    So, it seems that the state of can1 is crucial for my device on can0 to work properly. All I did then was to create a file called can1 in my /etc/network/interfaces.d which looks the following and which gets can1 up on startup:

    auto can1
    iface can1 inet manual
      pre-up /sbin/ip link set can1 type can bitrate 1000000
      up /sbin/ip link set up can1 && /sbin/modprobe can-dev
      down /sbin/ip link set down can1
    

    I am not sure if loading of the module in the "up" part of that configuration is neccessary here and - more important - has any disadvantages. If someone knows about that stuff better than me (and I am sure most of you linux people out there do), please let me know.

    In the end, the can bus works as expected without executing additional commands, right from startup.