When building a test setup with multiple CAN controllers, it is crucial to ensure persistent device names, no matter boot or enumeration order. The PCAN USB-FD devices by Peak do not export a USB serial number, making it difficult to write udev rules to match against them. Instead, the controllers provide a concept called a Device ID. This ID is a 32 bit integer that is stored in the device’s flash memory and can be freely set by the user. Notably, a unique ID can be set for each CAN controller, i.e. the ID is not really a device ID but rather a controller ID for devices with multiple controllers. Starting with Linux version 6.3, the kernel now has support for reading & writing the device ID. Additionally, it can be used as a udev match attribute.
Read & Write Support
The Device ID is called CAN Channel ID in the kernel to reduce the disambiguity mentioned above. It can be read and written with ethtool. The byte order is always little endian.
Reading
Given a PCAN device as can0:
1
ethtool -e can0
Writing
Given a PCAN device as can0:
1
echo "00 11 22 33" | xxd -r -p | ethtool -E can0
udev Support
The kernel exports a custom udev attribute for PCAN CAN controllers:
1
ls -l /sys/class/net/can0/peak_usb/can_channel_id
The file exports the Device ID attribute as a hex-encoded, little-endian 32 bit integer. The value is read-only, i.e. it can only be set via ethtool. A rule can be written as follows:
1
SUBSYSTEM=="net", ACTION=="add", KERNEL=="can*", ATTR{peak_usb/can_channel_id}=="00112233", NAME="mycan"