9. CAN总线

CAN总线协议(Controller Area Network), 控制器局域网总线,是德国BOSCH(博世)公司研发的一种串行通讯协议总线, 它可以使用双绞线来传输信号,是世界上应用最广泛的现场总线之一。

9.1. CAN硬件连接

鲁班猫4v1/鲁班猫5v2板卡40pin上的can为芯片原生接口,没有通过can收发器,使用的时候需要外接can收发器模块。

CAN收发器购买参考链接: 野火CAN收发器模块

核心板加底板形式的板卡,比如鲁班猫5IO,在底板上已经有CAN收发器,可以直接使用。

板卡和外部设备CAN接线如下:

板卡

外部设备

CAN_L

CAN_L

CAN_H

CAN_H

9.2. CAN

9.2.1. can配置

  • 开启和关闭can都需要重启才能生效

  1. 开启设备树插件(这里以打开CAN1为例)

1
2
#修改配置文件
vi /boot/uEnv/uEnv.txt
  • #dtoverlay=/dtb/overlay/rk3588-lubancat-can1-m1-overlay.dtbo 前面的#删除,如下图

未找到图片

注意

can1和canfd1不能同时开启

  1. 关闭设备树插件(这里以打开CAN1为例)

  • dtoverlay=/dtb/overlay/rk3588-lubancat-can1-m1-overlay.dtbo 前面添加#,如下图

未找到图片

9.2.2. can通信测试

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
查询当前网络设备:
ifconfig -a

CAN启动:
    关闭CAN:
    ip link set can0 down

    设置比特率500KHz:
    ip link set can0 type can bitrate 500000

    打印can0信息:
    ip -details link show can0

    启动CAN:
    ip link set can0 up

CAN发送:
    发送(标准帧,数据帧,ID:123,date:DEADBEEF):
    cansend can0 123#DEADBEEF

    发送(标准帧,远程帧,ID:123):
    cansend can0 123#R

    发送(扩展帧,数据帧,ID:00000123,date:DEADBEEF):
    cansend can0 00000123#12345678

    发送(扩展帧,远程帧,ID:00000123):
    cansend can0 00000123#R

CAN接收:
    开启打印,等待接收:
    candump can0

9.2.3. 更多指令

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
关闭can设备
ip link set canX down

开启can设备
ip link set canX up

显示can设备详细信息
ip -details link show canX

接收can总线发来数据
candump canX

关闭can设备,以便配置
ifconfig canX down

设置can波特率
ip link set canX up type can bitrate 250000

发送数据
cansend canX --identifier=ID+数据

使用滤波器接收ID匹配的数据
candump canX --filter=ID:mask

9.2.4. 简单的自收发脚本

将can1和can2对接起来,然后执行以下脚本,收发日志保存在/home/cat/log.txt

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#!/bin/bash

ip link set can0 down
ip link set can1 down
ip link set can0 type can bitrate 500000
ip link set can1 type can bitrate 500000
ip link set can0 up
ip link set can1 up

#监控can0数据
candump can0 >> /home/cat/log.txt &

counter=0
while true; do
    #can0发送can0 123#00000000~123#99999999数据
    data=$(printf "%08d" $counter)
    command="cansend can0 123#$data"
    echo $command
    $command

    #can1发送can0 321#00000000~321#99999999数据
    command2="cansend can1 321#$data"
    echo $command2
    $command2

    if [ $counter -eq 99999999 ]; then
        counter=0
    else
        counter=$((counter+1))
    fi
    sleep 0.01
done

9.2.5. can时钟频率修改

  1. 修改设备树插件上的时钟频率, kernel/arch/arm64/boot/dts/rockchip/overlay/rk3588-lubancat-canX-mY-overlay.dts (X,Y是各自的数字)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
/dts-v1/;
/plugin/;

#include <dt-bindings/clock/rk3588-cru.h>

/ {
    compatible = "rockchip,rk3588";

    fragment@0 {
        target = <&can1>;

        __overlay__ {
            status = "okay";
            compatible = "rockchip,can-1.0";
            assigned-clocks = <&cru CLK_CAN1>;
            assigned-clock-rates = <200000000>;
            pinctrl-names = "default";
            pinctrl-0 = <&can1m0_pins>;
        };
    };
};
  • assigned-clock-rates时钟频率可以修改,如果CAN的比特率1M建议修改CAN时钟到300M,信号更稳定。低于1M比特率的,时钟设置200M就可以,默认使用的是200M。

9.3. CAN FD

9.3.1. can fd配置

  • 开启和关闭can fd都需要重启才能生效

  1. 开启设备树插件(这里以打开CAN1 FD为例)

1
2
#修改配置文件
vi /boot/uEnv/uEnv.txt
  • #dtoverlay=/dtb/overlay/rk3588-lubancat-canfd1-m1-overlay.dtbo 前面的#删除,如下图

未找到图片

注意

can1和canfd1不能同时开启

  1. 关闭设备树插件(这里以打开CANFD1为例)

  • dtoverlay=/dtb/overlay/rk3588-lubancat-canfd1-m1-overlay.dtbo 前面添加#,如下图

未找到图片

9.3.2. can fd通信测试

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
查询当前网络设备:
ifconfig -a

CAN FD启动:
    关闭CAN:
    ip link set can0 down

    设置仲裁段1M波特率,数据段3M波特率:
    ip link set can0 type can bitrate 1000000 dbitrate 3000000 fd on

    打印can0信息:
    ip -details link show can0

    启动CAN:
    ip link set can0 up

    CAN FD发送:
    发送(标准帧,数据帧,ID:123,date:DEADBEEF):
    cansend can0 123##1DEADBEEF

    CAN FD接收:
    开启打印,等待接收:
    candump can0

9.3.3. 更多指令

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
关闭can设备
ip link set canX down

开启can设备
ip link set canX up

显示can设备详细信息
ip -details link show canX

接收can总线发来数据
candump canX

关闭can设备,以便配置
ifconfig canX down

设置仲裁段1M波特率,数据段3M波特率:
ip link set can0 type can bitrate 1000000 dbitrate 3000000 fd on

发送数据
cansend canX --identifier=ID+数据

使用滤波器接收ID匹配的数据
candump canX --filter=ID:mask

9.3.4. 简单的自收发脚本

将can1和can2对接起来,然后执行以下脚本,收发日志保存在/home/cat/log.txt

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#!/bin/bash

ip link set can0 down
ip link set can1 down
ip link set can0 type can bitrate 1000000 dbitrate 3000000 fd on
ip link set can1 type can bitrate 1000000 dbitrate 3000000 fd on
ip link set can0 up
ip link set can1 up

#监控can0数据
candump can0 >> /home/cat/log.txt &

counter=0
while true; do
    #can0发送can0 123#00000000~123#99999999数据
    data=$(printf "%08d" $counter)
    command="cansend can0 123##0$data"
    echo $command
    $command

    #can1发送can0 321#00000000~321#99999999数据
    command2="cansend can1 321##0$data"
    echo $command2
    $command2

    if [ $counter -eq 99999999 ]; then
        counter=0
    else
        counter=$((counter+1))
    fi
    sleep 0.01
done

9.3.5. can时钟频率修改

  1. 修改设备树插件上的时钟频率, kernel/arch/arm64/boot/dts/rockchip/overlay/rk3588-lubancat-canfdX-mY-overlay.dts (X,Y是各自的数字)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
/dts-v1/;
/plugin/;

#include <dt-bindings/clock/rk3588-cru.h>

/ {
    compatible = "rockchip,rk3588";

    fragment@0 {
        target = <&can1>;

        __overlay__ {
            status = "okay";
            compatible = "rockchip,canfd-1.0";
            pinctrl-names = "default";
            assigned-clocks = <&cru CLK_CAN1>;
            assigned-clock-rates = <100000000>;
            pinctrl-0 = <&can1m0_pins>;
        };
    };
};
  • assigned-clock-rates时钟频率可以修改,如果CAN的比特率低于等于3M建议修改CAN时钟到100M,信号更稳定。高于3M比特率的,时钟设置200M就可以,默认为100M