© SYSTEC electronic AG, D-08468 Heinsdorfergrund, Am Windrad 2
www.systec-electronic.com
- USB-CANmodul series generation 3 and 4
- AlmaLinux 9.3 instalation with kernel 5.14.0-362.18.1.el9_3.x86_64
- CAN utilities from the ATLAS repository (It is included in this repository)
- Following kernel options have to be set:
CONFIG_CAN=m
CONFIG_CAN_RAW=m
CONFIG_CAN_BCM=m
CONFIG_CAN_DEV=m
CONFIG_CAN_CALC_BITTIMING=y
$ sudo rpm -i CANUtilities.rpm
Remember to have DKMS, or else you wont be able to run it!
-
CAN frame reception and transmission:
- standard frame format (11 bit identifier)
- extended frame format (29 bit identifier)
- remote transmit request frames (RTR)
-
Supported CAN controller states:
CAN_STATE_ERROR_ACTIVE
(CAN bus runs error-free)CAN_STATE_ERROR_WARNING
(error counters reached warning limit)CAN_STATE_ERROR_PASSIVE
(node sends passive error frames)CAN_STATE_BUS_OFF
(node does not send any frames, i.e. it is virtually disconnected from bus)
-
Supported SocketCAN error frame flags (not to mix up with CAN error frames according to CAN specification)
struct can_frame frame;
....
if (frame.can_id & CAN_ERR_FLAG) {
if (frame.can_id & CAN_ERR_BUSOFF) {
/* BUS OFF */ }
if (frame.can_id & CAN_ERR_RESTARTED) {
/* recover from BUS OFF */ }
if (frame.can_id & CAN_ERR_CRTL) {
if (frame.data[1] & (CAN_ERR_CRTL_RX_WARNING |
CAN_ERR_CRTL_TX_WARNING)) {
/* warning limit reached */ }
if (frame.data[1] & (CAN_ERR_CRTL_RX_PASSIVE |
CAN_ERR_CRTL_TX_PASSIVE)) {
/* error passive state entered */ }
if (frame.can_id & CAN_ERR_PROT) {
if (frame.data[2] & CAN_ERR_PROT_ACTIVE) {
/* error active state entered */ }
}
}
}
-
Supported CAN controller modes
CAN_CTRLMODE_3_SAMPLES
(Triple sampling mode)CAN_CTRLMODE_LISTENONLY
(Listen-only mode)CAN_CTRLMODE_ONE_SHOT
(One-Shot mode, only for PIDs 0x1121, 0x1122, 0x1123 and 0x1125)
-
Tx echo is implemented in driver and there is optional support for hw based Tx echo.
- Firmware version >=4.06 must be installed on USB-CANmodul. In case of an older firmware version, please connect the USB-CANmodul to a Windows PC with a recent driver version. The Windows driver will update the firmware. Afterwards also this driver is capable of updating the firmware.
- There is currently no way to read out or set the digital I/Os of the user port or the CAN port (signals EN, /STB, /ERR, /TRM).
- No support for the obsolete modules GW-002 and GW-001. This is not planned at all.
- Planned CAN controller modes
CAN_CTRLMODE_LOOPBACK
(Loopback mode)
- After an update of firmware files, the Linux system has to be restarted for the system to use the newer ones, as the kernel caches firmware files on filename base.
- TO TAKE INTO ACCOUNT!!!!
- The original version of the driver was compatible with kernel 5.15. This kernel is not available in the AlmaLinux 9.3 repository. The driver was modified to be compatible with the 5.14.0-362.18.1.el9_3.x86_64 kernel. The driver was tested with this kernel and it worked correctly. The driver was not tested with other kernel versions.
- This modified driver (because the feature was introduced in 5.15, and does not exist in 5.14) does not support the can_led_event mode. Therefore, THE CAN LEDS WILL NOT WORK ON CERTAIN FIRMWARES.
$ sudo rpm -i CANUtilities.rpm
$ lsmod | grep can
Run make within the source directory
$ cd systec_can
$ make all
- If the CAN modules are not loaded, load basic CAN drivers
$ sudo modprobe can_raw
$ sudo modprobe can_dev
- Install firmware
$ sudo make firmware_install
- Load USB-CANmodul driver
$ sudo insmod systec_can.ko
The driver has the following module parameters:
-
debug (type int)
This is a bitmask enabling/disabling different parts of debug messages at module load time or during runtime.
It can be set during a manual insmod: e.g.insmod systec_can.ko debug=0x1
or use/etc/modprobe.d/
(actual path may depend on used version and/or distribution) for usage with modprobe and/or automatically load with udev.
All messages are still send with debug level, so a system logger may need to be configured accordingly.Available Bits:
- Bit 0: Generic driver debug message for module load/unload and interface up/down
- Bit 1: USB command message dump
- Bit 2: USB status message dump
- Bit 3: USB data message dump
- Bit 4: Tx related events (start and finish of USB transfer)
- Bit 5: Bittiming related output (e.g. settings like bitrate and sample point)
- Bit 6: USB command message events
- Bit 7: Error handling events
- Bit 8: Disconnect related events
-
hw_txecho (type boolean)
If set the CAN frame will be echoed when actually sent by the hardware. Any change to this flags will become effective when the interface is (re-)started.
-
When updating the bootloader from version 1.01 r2 it might happen that the device will not reconnect properly. LEDs are not indicating this. Workaround: Disconnect the device physically and reconnect it afterwards.
-
Rare, but possible out-of-order issues on SMP systems. See
- https://marc.info/?l=linux-can&m=148000256801316&w=2
- https://marc.info/?l=linux-can&m=143637774606287&w=2
Workaround: Write a bitmask (a bit for each CPU available being set) to
/sys/class/net/can0/queues/rx-0/rps_cpus
. e.g.echo f > /sys/class/net/can0/queues/rx-0/rps_cpus
for a system with 4 CPUs (both logical and physical)
-
Connect the USB-CANmodul to the PC
Note: Some of the following commands require the capability
CAP_NET_ADMIN
. So those commands should be executed as root (e.g. via sudo). -
Set bitrate to 125kBit/s
$ ip link set can0 type can bitrate 125000
OR if
CONFIG_CAN_CALC_BITTIMING
is undefined$ ip link set can0 type can tq 500 prop-seg 6 phase-seg1 7 phase-seg2 2
-
Start up the CAN interface
$ ip link set can0 up
-
Dump the traffic on the CAN bus
$ cd can-utils $ ./candump can0
to display error frames (option -e is supported in newer candump versions only):
$ ./candump -e can0,0:0,#FFFFFFFF
-
Transmit one CAN frame
$ cd can-utils $ ./cangen -n 1 -I 640 -L 8 -D 4000100000000000 can0
-
Print out some statistics
$ ip -details -statistics link show can0
-
Restart CAN channel manually in case of bus-off (i.e. short circuit)
$ ip link set can0 type can restart
Automatically restart the CAN channel 1000 ms after bus-off occurs
$ ip link set can0 type can restart-ms 1000
-
Increase the transmit queue length from default value 10 to 1000. 10 is the size of one CAN message.
$ ip link set can0 txqueuelen 1000
The hardware address (like the MAC address of Ethernet controllers)
of each CAN channel as shown with
ip link show can0
or ifconfig can0
is formed the following way:
S0:S1:S2:S3:DN:CN
- Sx - Serial Number in Hex with S0 contains the most significant byte
- DN - Device Number
- CN - Channel Number (00 - CAN1, 01 - CAN2)
The unique hardware address can be used by a special udev rule to assign stable interface names and numbers.
Note: The usage of hardware address for serial numbers to identify devices is discouraged by Kernel developers and might change.
The Device Number can be changed via the sysfs attribute devicenr
under
/sys/class/net/*/device/devicenr
(where * corresponds to the interface name like
can0
) or /sys/bus/usb/devices/*/devicenr
(where * corresponds to the USB device
path like 3-1:1.0
). Please note the hardware address will change after device
reset.
This USB interface attribute shows 0 for a single-channel device and 1 for a dual-channel device.
Any write to this USB interface reset the device.
This CAN interface attribute shows the channel number on the device.
This CAN interface attribute on a dual-channel device configures a timeout when a message shall be dropped, if it cannot be sent due to e.g. low CAN-ID priority, not connected bus, ...
In this case the other channel is blocked due to firmware restrictions. Using this timeout the other, correctly connected, channel can still be used.
This USB device attribute can read/write the status timeout in ms. When a CAN interface is active the status request URB must be send within this limit after the last one or the device will disconnect and reconnect itself.
A timeout of 0 means the check is disabled.
Any change will only take effect after power-on the USB-CAN-Module!
This USB device attribute can read/write the CAN clock speed. It shows 0 for slower clock speed (24 MHz) and 1 for higher performance (+25% clock speed = 30 MHz). To use the new setting, the device must be restarted (see sysfs attribute reset).
Example for udev rule (file /etc/udev/rules.d/20-systec-can.rules
):
# USB device 0x0878:0x1101 (systec_can)
# device number 01, first CAN channel -> can10
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="systec_can", \
ATTR{address}=="??:??:??:??:01:00", KERNEL=="can*", NAME="can10"
# USB device 0x0878:0x1101 (systec_can)
# device number 01, second CAN channel -> can11
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="systec_can", \
ATTR{address}=="??:??:??:??:01:01", KERNEL=="can*", NAME="can11"
# USB device 0x0878:0x1101 (systec_can)
# device connected at USB port 3-1:1.0, first CAN channel -> can20
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="systec_can", KERNELS=="3-1:1.0", \
ATTR{address}=="??:??:??:??:??:00", KERNEL=="can*", NAME="can20"
# USB device 0x0878:0x1101 (systec_can)
# device connected at USB port 3-1:1.0, second CAN channel -> can21
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="systec_can", KERNELS=="3-1:1.0", \
ATTR{address}=="??:??:??:??:??:01", KERNEL=="can*", NAME="can21"
# USB device 0x0878:0x1101 (systec_can)
# only set the timeout on dual channel devices
ACTION=="add", SUBSYSTEM=="net", DRIVERS=="systec_can", \
ATTRS{dual_channel}=="1", ATTR{tx_timeout_ms}="1000"
-
CAN utilities
-
Linux Kernel Source Code Documentation/networking/can.txt
-
Talk about SocketCAN - CAN Driver Interface under Linux (German, but slides in English)
-
libsocketcan V0.0.9 Helper library for CAN interface configuration (e.g. bitrate) over netlink API.
-
Can-Development Read the docs:
https://confluence.cern.ch/display/CANDev/CAN+development?src=sidebar