CAN/CAN-FD 驱动
1. 概述
1.1 功能简介
CAN(Controller Area Network)是一种用于汽车和工业控制的串行通信总线协议。RK3576 内置多路 CAN 控制器,支持 CAN 2.0B 和 CAN FD(Flexible Data-rate)协议,最高速率可达 8Mbps(CAN FD 数据段),适用于车载网络、工业自动化、机器人控制等场景。
1.2 应用场景
- 车载网络:汽车 OBD 诊断、仪表盘通信
- 工业控制:CAN 总线传感器、执行器通信
- 机器人:多关节电机控制、传感器数据采集
- 能源管理:储能系统、BMS 电池管理
- 自动化设备:PLC 通信、分布式控制系统
1.3 工作原理
CAN 采用多主架构,通过差分信号(CAN_H、CAN_L)通信。CAN FD 在经典 CAN 基础上扩展了数据段速率和帧长度:
| 特性 | CAN 2.0B | CAN FD |
|---|---|---|
| 数据速率 | 最高 1Mbps | 最高 8Mbps |
| 数据长度 | 最多 8 字节 | 最多 64 字节 |
| 帧格式 | 标准/扩展帧 | CAN FD 帧 |
| 仲裁 | 11/29 位 ID | 11/29 位 ID |
详见 RK 官方文档:[《Rockchip_Developer_Guide_Linux_Software_CN.pdf》]
2. 硬件准备
2.1 硬件清单
| 组件 | 型号/规格 | 数量 | 备注 |
|---|---|---|---|
| 主控板 | C-3576BQ 核心板 + M4-R2 底板 | 1 | |
| 调试串口线 | USB 转 TTL(3.3V) | 1 | 波特率 1500000 |
| CAN 收发器模块 | TJA1050 / SN65HVD230 | 1 | 3.3V CAN 收发器 |
| CAN 分析仪(可选) | PCAN / CANalyst-II | 1 | 用于 CAN 通信调试 |
| 杜邦线 | 母对母 | 若干 | |
| 120Ω 终端电阻 | 1/4W | 2 | CAN 总线两端 |
2.2 引脚连接
以 CAN1 为例:
| 主控板引脚 | CAN 收发器引脚 | 功能说明 |
|---|---|---|
| CAN1_TX(底板标注) | TXD | CAN 发送 |
| CAN1_RX(底板标注) | RXD | CAN 接收 |
| 3.3V | VCC | 收发器电源 |
| GND | GND | 共地 |
| CAN 收发器引脚 | CAN 总线 | 功能说明 |
|---|---|---|
| CAN_H | CAN_H | CAN 高电平 |
| CAN_L | CAN_L | CAN 低电平 |
CAN 引脚在底板原理图中有标注。M4-R2 底板具体引出哪些 CAN 通道,以实际原理图与 SDK 配置为准(待板上验证)。实际操作时应确认 CAN 收发器方向(TXD/RXD 是否交叉)。
2.3 硬件确认
# 查看 CAN 网络接口
ip link show type can
# 输出示例:can0 can1 ...
# 查看 CAN 接口详细信息
ip -details link show can03. 软件准备
3.1 内核配置
确认以下内核配置已启用:
CONFIG_CAN=y
CONFIG_CAN_VCAN=y
CONFIG_CAN_RAW=y
CONFIG_CAN_BCM=y
CONFIG_CAN_GS_CAN=y
CONFIG_CAN_ROCKCHIP=y
CONFIG_OF=y
CONFIG_CAN_ROCKCHIP是 Rockchip CAN 控制器驱动,适用于 RK3576。
3.2 设备树
RK3576 的 CAN 控制器在设备树中定义(以下为 RK 平台通用结构示例):
can1: can@fea80000 {
compatible = "rockchip,rk3576-can", "rockchip,rk3568-can";
reg = <0x0 0xfea80000 0x0 0x1000>;
interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru CLK_CAN1>, <&cru PCLK_CAN1>;
clock-names = "can", "apb_pclk";
resets = <&cru SRST_CAN1>, <&cru SRST_H_CAN1>;
reset-names = "can", "can-apb";
status = "disabled";
};以上寄存器基地址、中断号与时钟标识为 RK 平台通用结构示例,具体数值以实际发布的 RK3576 SDK 设备树为准(待板上确认)。
4. 操作步骤
4.1 配置 CAN 接口
# 设置 CAN 接口波特率并启动
ip link set can0 type can bitrate 500000 # 500kbps
ip link set can0 up
# CAN FD 模式
ip link set can0 type can bitrate 500000 dbitrate 2000000 fd on
ip link set can0 up
# 查看 CAN 接口状态
ip -details link show can0
# 停止 CAN 接口
ip link set can0 down4.2 发送和接收 CAN 帧
# 安装 can-utils 工具
apt-get install can-utils
# 发送标准帧(can0 发送 ID 0x123,数据 0x11 0x22 0x33)
cansend can0 123#112233
# 发送扩展帧(29 位 ID)
cansend can0 12345678#1122334455667788
# 发送 CAN FD 帧
cansend can0 123##1.1122334455667788AABBCCDDEEFF00
# 接收 CAN 帧(持续监听)
candump can0
# 接收特定 ID 的帧
candump can0,123:7FF # 掩码过滤
# 使用 candump 保存到文件
candump can0 > can_log.txt &4.3 CAN FD 操作
# 启用 CAN FD
ip link set can0 type can bitrate 500000 dbitrate 4000000 fd on
ip link set can0 up
# 发送 CAN FD 帧(BRS=1,数据段加速)
cansend can0 123##1.1122334455667788AABBCCDDEEFF00
# 查看 CAN FD 统计
cat /sys/class/net/can0/statistics/tx_bytes
cat /sys/class/net/can0/statistics/rx_bytes4.4 设备树中配置 CAN
&can1 {
status = "okay";
pinctrl-0 = <&can1m0_xfer &can1m0_txen>;
pinctrl-names = "default";
rockchip,can-clk-Source = <0>; // 时钟源选择
};4.5 通过 debugfs 查看 CAN 信息
# 查看 CAN 控制器状态
cat /sys/kernel/debug/can/registers
# 查看 CAN 错误计数
cat /sys/class/net/can0/statistics/5. 代码详解
5.1 内核中 CAN 驱动的注册
// RK3576 CAN 控制器驱动(简化)
// drivers/net/can/rockchip/rockchip_canfd.c
static struct platform_driver rockchip_can_driver = {
.probe = rockchip_can_probe,
.remove = rockchip_can_remove,
.driver = {
.name = "rockchip-can",
.of_match_table = rockchip_can_match,
},
};
static const struct of_device_id rockchip_can_match[] = {
{ .compatible = "rockchip,rk3576-can" },
{ /* sentinel */ }
};5.2 用户空间 CAN 操作的内核调用链
用户空间 cansend can0 123#112233
→ socket(PF_CAN, SOCK_RAW, CAN_RAW)
→ bind() 绑定 CAN 接口
→ write() 发送 CAN 帧
→ can_send()
→ rockchip_can_start_xmit()
→ 将数据写入 CAN 发送缓冲区6. 常见问题
6.1 CAN 接口无法启动
现象: ip link set can0 up 报错
解决方案:
# 检查 CAN 接口是否存在
ip link show type can
# 检查 CAN 控制器时钟
cat /sys/kernel/debug/clk/clk_can1/clk_rate
# 检查设备树中 CAN 节点状态
# 具体节点路径以实际 DTB 反编译结果为准
dtc -I dtb -O dts /sys/firmware/fdt | grep -A3 "can@"确认设备树中 CAN 节点 status = "okay",且 CAN 收发器硬件连接正确。
6.2 CAN 通信无数据
现象: cansend 发送成功但 candump 无输出
解决方案:
# 检查 CAN 接口统计
ip -s link show can0
# 检查 CAN 总线终端电阻(两端各 120Ω)
# 检查 CAN_H 和 CAN_L 差分信号确认 CAN 总线两端接 120Ω 终端电阻,检查收发器方向(TXD/RXD 是否交叉)。
6.3 CAN 错误帧
现象: candump 显示大量错误帧
解决方案:
# 查看 CAN 错误计数器
cat /sys/class/net/can0/statistics/rx_errors
cat /sys/class/net/can0/statistics/tx_errors
# 重启 CAN 接口
ip link set can0 down
ip link set can0 type can bitrate 500000
ip link set can0 up检查 CAN 总线终端电阻、收发器供电、信号完整性。
