玩转Linux CAN/CAN FD—SocketCAN的使用
导语:
SocketCAN是CAN协议在Linux系统上的一种主流的实现方式,SocketCAN使用套接字API、Linux网络栈技术,将CAN设备驱动程序实现为网络接口,使其有着易用、兼容性好等特点。
更多SocketCAN的详情可以查看以下文档:
https://www.kernel.org/doc/html/v4.17/networking/can.html
本文将从驱动(内核、pcan驱动)到使用(can-utils),带你轻松入门socketcan。
一、配置
本节将从驱动、查找设备、设置波特率、设备状态等几个方面进行介绍。
驱动检查:
检查设备是否已经安装CAN驱动模块
lsmod | grep peak_usb
如果有返回结果,说明设备此时有驱动,可以直接使用;
如果没返回结果,就尝试安装驱动。
sudo modprobe peak_usb
安装成功后,再次使用第一条命令检查;
若返回如下命令,则表示内核中没有包含驱动。
modprobe: FATAL: Module peak_usb not found in directory /lib/modules/6.8.0-60-generic
如果缺少驱动,有两种处理方法:
-
重新配置&编译Linux内核(推荐)
-
手动安装独立设备驱动
推荐使用安装内核的方式,安装后与系统的适配性更好。详细操作方法会在文章最后介绍。
查找设备:
检查完驱动后,确保CAN设备已连接,查找设备接口。
$ ip link show
4: can0: <NOARP,UP,LOWER_UP> mtu 72 qdisc pfifo_fast state UP mode DEFAULT group default qlen 10link/can
5: can1: <NOARP,UP,LOWER_UP> mtu 16 qdisc pfifo_fast state UP mode DEFAULT group default qlen 10link/can
另一种方法
$ ifconfig -a
can0: flags=193<UP,RUNNING,NOARP> mtu 72unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 10 (UNSPEC)RX packets 0 bytes 0 (0.0 B)RX errors 49043711 dropped 10685 overruns 0 frame 0TX packets 6563 bytes 105195 (105.1 KB)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
can1: flags=193<UP,RUNNING,NOARP> mtu 16unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 10 (UNSPEC)RX packets 2839 bytes 46278 (46.2 KB)RX errors 46143779 dropped 1270 overruns 0 frame 0TX packets 1440 bytes 21090 (21.0 KB)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
波特率设置:
确认设备接口信息后,设置波特率。
配置can0设备的波特率设定为500k bps,命令如下:
sudo ip linkset can0 type can biterate 500000
如果是支持CAN FD的设备,则可以使用以下命令,配置can0为CAN FD 格式波特率500k/2M
sudo ip linkset can0 type can bitrate 500000 dbitrate 2000000 fd on
指定采样率等高级的参数配置,下面的操作配置总裁段波特率500K采样75%,数据段波特率4M采样点80%。
sudo ip linkset can0 type can bitrate 500000 sample-point 0.75 dbitrate 4000000 dsample-point 0.8 fd on
在波特率配置完成后,启动can设备(设备启动后无法修改波特率)
sudo ip linkset can0 up
关闭can设备
sudo ip linkset can0 down
以下是常用的一些使用配置,还有很多关于can接口的配置命令,使用help指令可轻松查找。
$ sudo ip linkset can0 type can help
Usage: ip linkset DEVICE type can[ bitrate BITRATE [ sample-point SAMPLE-POINT] ] |[ tq TQ prop-seg PROP_SEG phase-seg1 PHASE-SEG1phase-seg2 PHASE-SEG2 [ sjw SJW ]][ dbitrate BITRATE [ dsample-point SAMPLE-POINT] ] |[ dtq TQ dprop-seg PROP_SEG dphase-seg1 PHASE-SEG1dphase-seg2 PHASE-SEG2 [ dsjw SJW ] ][ loopback { on | off } ][ listen-only { on | off } ][ triple-sampling { on | off } ][ one-shot { on | off } ][ berr-reporting { on | off } ][ fd { on | off } ][ fd-non-iso { on | off } ][ presume-ack { on | off } ][ cc-len8-dlc { on | off } ][ restart-ms TIME-MS ][ restart ][ termination { 0..65535 } ]Where: BITRATE := { 1..1000000 }SAMPLE-POINT := { 0.000..0.999 }TQ := { NUMBER }PROP-SEG := { 1..8 }PHASE-SEG1 := { 1..8 }PHASE-SEG2 := { 1..8 }SJW := { 1..4 }RESTART-MS := { 0 | NUMBER }
在上方高亮标记的配置中,有两点需要注意的
-
波特率设置:推荐使用直接设置波特率方式进行配置,程序会自动根据波特率提供较优的时间参数;通过配时间参数设备波特率,需要对此有一定的基础,否则容易出错。
-
berr-reporting:有些配置教程里会有开启错误报告的设置,但PCAN驱动不支持此功能,请勿启用。
CAN接口状态:
下面的命令用于查看详细的CAN波特率配置参数、设备状态。
$ ip -d link show
4: can0: <NOARP> mtu 72 qdisc pfifo_fast state DOWN mode DEFAULT group default qlen 10link/can promiscuity 0 minmtu 0 maxmtu 0 can <FD> state STOPPED (berr-counter tx 0 rx 0) restart-ms 0 bitrate 1000000 sample-point 0.750 tq 12 prop-seg 29 phase-seg1 30 phase-seg2 20 sjw 10pcan: tseg1 1..256 tseg2 1..128 sjw 1..128 brp 1..1024 brp-inc 1dbitrate 2000000 dsample-point 0.750 dtq 12 dprop-seg 14 dphase-seg1 15 dphase-seg2 10 dsjw 5pcan: dtseg1 1..32 dtseg2 1..16 dsjw 1..16 dbrp 1..1024 dbrp-inc 1clock 80000000 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
5: can1: <NOARP,UP,LOWER_UP> mtu 16 qdisc pfifo_fast state UP mode DEFAULT group default qlen 10link/can promiscuity 0 minmtu 0 maxmtu 0 can state ERROR-PASSIVE (berr-counter tx 0 rx 127) restart-ms 0 bitrate 1000000 sample-point 0.750 tq 12 prop-seg 29 phase-seg1 30 phase-seg2 20 sjw 10pcan: tseg1 1..256 tseg2 1..128 sjw 1..128 brp 1..1024 brp-inc 1pcan: dtseg1 1..32 dtseg2 1..16 dsjw 1..16 dbrp 1..1024 dbrp-inc 1clock 80000000 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
通过ip -d link show,我们可以得到CAN设备状态是启动或关闭,运行状态,错误计数器,以及波特率详细参数。
异常恢复:
can <FD> state BUS-OFF (berr-counter tx 248 rx 127) restart-ms 0
当设备进入busoff等异常状态时,可以通过以下命令重新启动设备。
sudo ip link set canX down
sudo ip link set canX up
更多有关CAN总线错误状态和错误管理的介绍可参考下文
[技术干货]CAN BUS的错误检测和错误状态管理
二、can-utils使用方法
can-utils是Linux下操作CAN总线的标准工具集,专为SocketCAN设计,包含多种can的实用工具,如candump、cansend等。
首先通过以下命令来安装can-utils:
sudo apt-get install can-utils
candump
candump可以实时显示接收到的can消息。
实时显示设备can0上的所有can消息,命令终端中输入以下命令:
candump can0
candump还可以使用掩码和标识符对接收到的can信息进行过滤。有两种过滤器类型:
-
[can_id]:[can_mask] :当[received_can_id] & [can_mask] == [can_id] & [mask] 被显示
-
[can_id]~[can_mask] :当[received_can_id] & [can_mask] != [can_id] & [mask] 被显示
例如:
仅显示can0上收到的ID为0x123的消息:
candump vcan0,0x123:0x7FF
仅显示can0上收到的ID为0x123或0x456的消息:
candump vcan0,0x123:0x7FF,0x456:0x7FF
更多candump功能可以通过candump -h查看(以下工具也相同)
candump -h
cansend
cansend可以将单个CAN帧发送到总线上。您将必须指定设备,标识符和要发送的数据字节。
例如:
cansend can0 123#1122334455667788
此条指令将在接口can0上发送一条消息,其标识符为0x123,数据字节为[0x11、0x22、0x33、0x44、0x55、0x66、0x77、0x88]。请注意,此工具始终假定值以十六进制给出。
cangen
cangen可以生成随机的CAN数据,这对于测试很有用。
例如,can0间隔100ms发一帧64位的随机CAN FD数据:
cangen can0 -f -g 100 -L 64
cansniffer
cansniffer可以显示总线上接收到的CAN消息,而且可以过滤掉数据不变的帧。这对于逆向工程CAN总线系统非常有用。
例如,将can0接收到的变化的消息打印出来,并将变化的字节高亮表示:
cansniffer -c can0
canbusload
canbusload可以用于实时显示处于工作状态(link up)的CAN设备的当前负载率。
举例:
user$> canbusload can0@100000 can1@500000,2000000 can2@500000 -r -t -b -c
canbusload 2024-08-08 16:30:05 (worst case bitstuffing)
can0@100k 192 21980 9136 0 21% |TTTT................|
can1@500k/2M 2651 475500 234448 131825 74% |XXXXXXXXXXXXXX......|
can2@500k 855 136777 62968 35219 27% |RRRRR...............|
三、Linux下PCAN驱动安装
配置内核自带驱动
查看设备内核配置:
$ grep PEAK_ /boot/config-`uname -r`
CONFIG_CAN_PEAK_PCIEFD=m
CONFIG_CAN_PEAK_PCI=m
CONFIG_CAN_PEAK_PCIEC=y
CONFIG_CAN_PEAK_PCMCIA=m
CONFIG_CAN_PEAK_USB=m
只需要注意CAN_PEAK_USB这项是否为m(独立模块),或是y(加载到内核),一般推荐设置为m。
若不是,则将该项修改为m或y,并重新编译内核即可。
pcan独立驱动的编译安装
因为Linux内核环境的多样性,在安装过程中可能会出现意料之外的错误,需要自身有一定处理问题的能力。
下载驱动并解压进入目录:
wget https://www.peak-system.com/fileadmin/media/linux/files/peak-linux-driver-8.20.0.tar.gz
tar –xzf peak-linux-driver-X.Y.Z.tar.gz
cd peak-linux-driver-X.Y.Z
编译驱动并启用Netdev支持,否则默认为Chardev:
make clean
make -C driver NET=NETDEV_SUPPORT
sudo make install
加载驱动:
sudo modprobe pcan
查看驱动是否存在:
lsmod | grep pcan
查看CAN接口是否存在:
Ifconfig -a
四、总结
篇幅有限,本文只是对SocketCAN进行了简单介绍,以及基础使用说明。
下一篇文章中将为大家介绍,专为SocketCAN设计的标准工具集——can-utils,欢迎关注。
支持linuxSocketCAN的设备-SYSMAX 雪球电子PCAN系列
SYSMAX 雪球电子的PCAN-USB, PCAN PRO, PCAN FD都支持Linux SocketCAN,并且linux系统已经包含驱动程序,无需安装驱动,可以做到即插即用。
PCAN系列设备软硬件设计以及linux驱动程序都已经相当成熟,在ROS机器人控制系统,工控机,汽车领域已取得广泛应用。是高可靠行业的不二之选。