返回所有文章
快速开始 / TSENGCHEN BLOG

RK3576_CAN_Quick_Start

08_QuickStart · RK3576_CAN_Quick_Start

08_QuickStart · 第 3 / 5 篇

保留原笔记正文与技术内容,仅脱敏敏感信息。配图按作者要求保留原样。

检索引脚复用情况 IOMUX

查 CAN0 所有复用组定义:

rg -n "can0|can0m[0-3]_pins|can0_rx|can0_tx" \
  kernel/arch/arm64/boot/dts/rockchip/rk3576-pinctrl.dtsi

查 CAN0 复用组有没有被引用:

rg -n "can0m0_pins|can0m1_pins|can0m2_pins|can0m3_pins" \
  kernel/arch/arm64/boot/dts/rockchip/

查 can0m0 对应 GPIO2_A0/A1 是否被占用:

rg -n "gpio2 RK_PA0|gpio2 RK_PA1|GPIO2_A0|GPIO2_A1|RK_PA0|RK_PA1" \
  kernel/arch/arm64/boot/dts/rockchip/rk3576*.dts*

板子运行后查实际 pinmux:

cat /sys/kernel/debug/pinctrl/*/pinmux-pins | grep -i can

查 GPIO 是否被驱动占用:

cat /sys/kernel/debug/gpio

设备树

三层关系:

rk3576.dtsi          定义 SoC 里有 CAN0 控制器,但默认 disabled
rk3576-pinctrl.dtsi  定义 CAN0 可以复用到哪些 GPIO 引脚
rk3576-test1.dtsi    板级文件,决定这块板子到底启用哪个外设、用哪组引脚

所以我们要写的是:在 rk3576-test1.dtsi 里启用 &can0,并指定它使用哪组 pinctrl。

一、先看 SoC 里 CAN0 怎么定义

查命令:

rg -n "can0:|rockchip,rk3576-can|CLK_CAN0|SRST_CAN0" \
  kernel/arch/arm64/boot/dts/rockchip/rk3576.dtsi

芯片层级设备树:

can0: can@2ac00000 {
        compatible = "rockchip,rk3576-can";
        reg = <0x0 0x2ac00000 0x0 0x1000>;
        interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
        clocks = <&cru CLK_CAN0>, <&cru HCLK_CAN0>;
        clock-names = "baudclk", "apb_pclk";
        resets = <&cru SRST_CAN0>, <&cru SRST_H_CAN0>;
        reset-names = "can", "can-apb";
        status = "disabled";
};

逐行意思:

can0: can@2ac00000 {

这是 CAN0 控制器节点。can0: 是 label,后面板级文件可以用 &can0 引用它。

compatible = "rockchip,rk3576-can";

告诉内核用哪个 CAN 驱动匹配这个硬件。

reg = <0x0 0x2ac00000 0x0 0x1000>;

CAN0 寄存器地址,驱动会映射这段寄存器。

interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;

CAN0 中断号。

clocks = <&cru CLK_CAN0>, <&cru HCLK_CAN0>;
clock-names = "baudclk", "apb_pclk";

CAN0 需要两个时钟,一个用于 CAN 波特率,一个用于 APB 总线访问。

resets = <&cru SRST_CAN0>, <&cru SRST_H_CAN0>;
reset-names = "can", "can-apb";

CAN0 的复位控制。

status = "disabled";

默认关闭。SoC 公共文件里通常都这样写,板级文件再决定是否开启。

板级设备树开启can0:

在 [rk3576-test1.dtsi](/home/user/kernel/arch/arm64/boot/dts/rockchip/rk3576-test1.dtsi) 里加:

&can0 {
        assigned-clocks = <&cru CLK_CAN0>;
        assigned-clock-rates = <200000000>;
        pinctrl-names = "default";
        pinctrl-0 = <&can0m0_pins>;
        status = "okay";
};

逐行解释:

&can0 {

引用 rk3576.dtsi 里已经定义好的 can0: can@2ac00000 节点。不是新建 CAN0,而是修改已有节点。

assigned-clocks = <&cru CLK_CAN0>;

指定要配置 CAN0 的工作时钟。

assigned-clock-rates = <200000000>;

把 CAN0 时钟设置为 200MHz。Rockchip 同系列 rk3576-industry.dtsi 里也是这样写的。

pinctrl-names = "default";

表示默认状态使用下面这组 pinctrl。

pinctrl-0 = <&can0m0_pins>;

指定 CAN0 使用 can0m0_pins,也就是 GPIO2_A0 做 RX,GPIO2_A1 做 TX。

status = "okay";

真正启用 CAN0。没有这一行,前面写了 pinctrl 也不会启用设备。

验证

编译 DTB:

cd kernel
make ARCH=arm64 rk3576-test1-v10-linux.dtb

如果编译报错,常见问题是:

Label or path can0m0_pins not found

说明 pinctrl label 没包含进来或名字写错。

syntax error

多半是分号、尖括号、花括号漏了。

板子启动后查:

dmesg | grep -i can
ip link show

如果成功,一般能看到 can0。

再看 pinmux:

cat /sys/kernel/debug/pinctrl/*/pinmux-pins | grep -i can

如果 ip link show 没有 can0,继续查内核配置:

zcat /proc/config.gz | grep CAN

至少要确认 CAN 框架和 Rockchip CAN 驱动打开。

编译内核

cd /home/user
./build.sh lunch
./build.sh kernel

ADB检测CAN是否开启

ifconfig -a
ip -details -statistics link show can0
ip -details -statistics link show can1

CAN 常用命令接口

  1. 查询当前网络设备:

ifconfig -a

  1. CAN启动:

关闭CAN:

ip link set can0 down

设置比特率500KHz:

ip link set can0 type can bitrate 500000

打印can0信息:

ip -details -statistics link show can0

启动CAN:

ip link set can0 up

  1. 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

  1. CAN接收:

开启打印,等待接收:

candump can0

检测各种模式的CAN

普通 CAN:

ip link set can0 down
ip link set can0 type can bitrate 500000
ip link set can0 up
candump can0
cansend can0 123#DEADBEEF

Pasted image 20260715104655 CAN FD 不带 BRS:

ip link set can0 down
ip link set can0 type can bitrate 1000000 dbitrate 3000000 fd on
ip link set can0 up
candump can0
cansend can0 123##0DEADBEEF

CAN FD 带 BRS:

ip link set can0 down
ip link set can0 type can bitrate 1000000 dbitrate 3000000 fd on
ip link set can0 up
candump can0
cansend can0 123##1DEADBEEF

回环测试,普通 CAN:

ip link set can0 down
ip link set can0 type can bitrate 500000 loopback on
ip link set can0 up
candump can0
cansend can0 123#DEADBEEF

回环测试,CAN FD:

ip link set can0 down
ip link set can0 type can bitrate 1000000 dbitrate 3000000 fd on loopback on
ip link set can0 up
candump can0
cansend can0 123##1DEADBEEF

监听模式:

ip link set can0 down
ip link set can0 type can bitrate 500000 listen-only on
ip link set can0 up
candump can0

错误帧抓取:

ip link set can0 down
ip link set can0 type can bitrate 500000 berr-reporting on
ip link set can0 up
candump -e can0

单次发送:

ip link set can0 down
ip link set can0 type can bitrate 500000 one-shot on
ip link set can0 up
cansend can0 123#DEADBEEF
08_QuickStart · 文档目录
上一篇RK3562-SPI-NAND-Quick_Start下一篇RK3576_test1_FPGA_DSMC_Quick_Start