news 2026/2/17 1:33:08

【瑞芯微平台实时Linux方案系列】第十三篇 - 瑞芯微平台CAN总线实时通信方案

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【瑞芯微平台实时Linux方案系列】第十三篇 - 瑞芯微平台CAN总线实时通信方案

一、简介:为什么要在瑞芯微上“硬实时”驱动 CAN?

  • 国产芯趋势:瑞芯微 RK3568/RK3588 四核 A55+A76,自带 PCIe 2.1、USB3.0,价格≅同行 1/2,已被大量工业网关、机械臂控制器采用。

  • 实时痛点:原生 Linux CAN 驱动默认threaded interrupt+ksoftirqd调度,中断延迟 80-120 μs,无法满足 ≤50 μs 轮询周期。

  • 本文目标:基于 PREEMPT_RT 5.15 + 瑞芯微 BSP,把 CAN 中断响应降到 ≤30 μs,增加“总线故障快照”与“自动重同步”机制,一套方案同时搞定实时性+可靠性


二、核心概念:5 个关键词先搞懂

关键词一句话瑞芯微对应
CAN Controller实现 CAN 2.0B/CAN-FD 协议逻辑RK3568 内置 2×M_CAN IP
Message RAMM_CAN 内部 FIFO,减少 DMA 搬运每条 CAN 64 kB
Interrupt Latency中断触发→ISR 第一条指令时间目标 ≤30 μs
SocketCANLinux 标准 CAN 框架,用户空间socket(AF_CAN,...)统一接口
Fault Confinement错误计数器 >96 警告,>255 总线关闭驱动自动快照

三、环境准备:10 分钟搭好开发机

1. 硬件

  • RK3568 工业核心板(友善、-firefly、自画均可)

  • 2×CAN-FD 收发器 TJA1057(支持 5 Mbps)

  • USB-CAN 卡(PC 端做对比测试)

2. 软件

组件版本获取
瑞芯微官方 SDKv1.2.1GitHub 开源
实时内核linux-5.15-rt47见下文一键脚本
交叉工具链gcc-linaro-11.3官方预编译
测试工具can-utils 2021.12.0apt install can-utils

3. 一键打 RT 补丁(可复制)

#!/bin/bash # rt_patch.sh VER=5.15 RT_PATCH=patch-5.15-rt47.patch.xz wget https://mirrors.edge.kernel.org/pub/linux/kernel/projects/rt/${VER}/${RT_PATCH} tar -xf linux-${VER}.tar.xz cd linux-${VER} xzcat ../${RT_PATCH} | patch -p1 make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- rockchip_linux_defconfig ./scripts/config -e CONFIG_PREEMPT_RT make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j$(nproc) Image dtbs

四、应用场景:边缘视觉+运动控制一体机

背景:3C 装配线要在 500 mm/s 速度下对手机中框拍照+打螺丝,拍摄窗口仅 10 mm → 允许延迟 ≤20 ms。
系统拓扑

RK3568 ├─ PCIe ×1 ← 2 MP 工业相机 (MJPEG 1 Gbps) ├─ CAN0 ← 伺服驱动器 (周期 1 ms,同步 6 轴) ├─ CAN1 ← 传感器握手机制 └─ GPIO ← 触发拍照

实时需求

  • CAN 周期帧抖动 ≤50 μs

  • 相机触发→GPIO 输出 ≤100 μs

  • 总线错误恢复 ≤100 ms

本文聚焦CAN 硬实时 + 故障自恢复,视觉触发部分后续篇章展开。


五、实际案例与步骤:从设备树到用户空间

5.1 硬件连接 & 管脚复用

RK3568 CAN0 引脚:

  • TX: GPIO3_B5

  • RX: GPIO3_B6

设备树片段rk3568.dtsi已含 M_CAN,只需使能):

&can0 { status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&can0m0_pins>; assigned-clocks = <&cru CLK_CAN0>; assigned-clock-rates = <200000000>; /* 200 MHz */ /* * Message RAM 偏移,避免与 GPU 冲突 * 偏移 0x100000,长度 64 KB */ m_can,msg-ram = <0x100000 0x10000>; /* 中断 affinity → CPU0 (RT 核) */ interrupt-affinity = <&cpu0>; };

5.2 驱动修改:中断线程化→hardirq

默认驱动drivers/net/can/m_can/m_can.c使用threaded_irq,延迟大。
改动点(diff 节选):

// 原: devm_request_threaded_irq() // 新: devm_request_irq(..., IRQF_NO_THREAD, ...)
  • 在 probe 里设置IRQF_NO_THREAD标志,让 M_CAN 中断直接进入 hardirq,RT 内核下可绑定到隔离核。

5.3 中断 affinity & CPU 隔离

启动参数

isolcpus=1 nohz_full=1 rcu_nocbs=1 quiet splash

把 CAN0 中断绑到 CPU0(非隔离核,保证 hardirq)

echo 1 > /proc/irq/32/smp_affinity_list # 32 为 CAN0 中断号

5.4 波特率 & CAN-FD 数据段配置

# 设置 1 Mbps / 5 Mbps FD sudo ip link set can0 type can bitrate 1000000 dbitrate 5000000 fd on sudo ip link set up can0

5.5 实时发送测试(C 代码)

/* rt_send.c */ #include <linux/can.h> #include <linux/can/raw.h> #include <net/if.h> #include <sys/socket.h> #include <unistd.h> #include <time.h> int main() { int s = socket(PF_CAN, SOCK_RAW, CAN_RAW); struct sockaddr_can addr = { .can_family = AF_CAN }; struct ifreq ifr = { .ifr_name = "can0" }; ioctl(s, SIOCGIFINDEX, &ifr); addr.can_ifindex = ifr.ifr_ifindex; bind(s, (struct sockaddr *)&addr, sizeof(addr)); struct canfd_frame frame = { .can_id = 0x123, .len = 64, .flags = CANFD_FDF, }; /* 填充 64 byte 数据 */ for (int i = 0; i < 64; i++) frame.data[i] = i; /* 周期 1 ms,硬实时循环 */ struct timespec ts = {0, 1000*1000}; /* 1 ms */ while (1) { clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL); send(s, &frame, sizeof(frame), MSG_DONTWAIT); } return 0; }

编译

aarch64-linux-gnu-gcc rt_send.c -o rt_send -pthread -O2

运行后,PC 端 USB-CAN 卡可测得周期抖动≤30 μs(示波器抓帧起始)。


5.6 故障诊断与自恢复

总线错误中断

ERR Passive → 错误计数器 > 96 Bus Off → 错误计数器 > 255

驱动层处理

if (irq_status & M_CAN_IR_BO) { /* Bus Off */ stats->bus_off++; can_bus_off(ndev); /* 通知 SocketCAN 框架 */ schedule_work(&priv->bus_off_work); /* 延后复位,避免 ISR 阻塞 */ }

工作函数

static void bus_off_work(struct work_struct *work) { struct m_can *priv = container_of(work, struct m_can, bus_off_work); msleep(100); /* 等待总线安静 */ m_can_reset(priv); /* 软件复位 M_CAN */ m_can_start(priv); netif_wake_queue(priv->ndev); }

用户空间感知:

ip -details link show can0 # 状态切换: UP → BUS-OFF → UP

恢复时间≈110 ms,满足产线“暂停-重启”窗口。


六、常见问题与解答(FAQ)

问题现象解决
设置 5 Mbps FD 失败Bitrate not supported确认收发器 TJA1057 支持 5 Mbps,dts 里 dbitrate 与采样点正确
中断延迟 > 80 μs未关 threaded_irq驱动里改用devm_request_irq+IRQF_NO_THREAD
can0 up 后无数据终端电阻 120 Ω 未接CAN_H-CAN_L 间量电阻,缺则并 120 Ω
大量丢帧dmesg 报Rx FIFO overrun增大 Message RAM 长度,或提高工作队列优先级
热插拔节点后错误帧暴增线缆反射使用双绞屏蔽线,屏蔽层单端接地

七、实践建议与最佳实践

  1. 中断隔离
    相机 DMA、网络 NIC 中断绑到非 RT 核,避免抢占 CAN hardirq。

  2. 提前计算采样点
    推荐数据段采样点 75%,可用cancalc工具一键生成 dts 时序值。

  3. 日志分级
    生产环境关闭can.debug,打开can.err级别,减少上下文切换。

  4. 双 CAN 冗余
    高安全场景使能can0+can1bond(SocketCAN redundancy 模块),单总线 Bus-Off 自动切换。

  5. 产线老化测试
    48 h 连续 FD 帧 5 Mbps 打流,错误帧 <0.001% 视为通过。

  6. 文档化
    把中断号、CPU 亲和、dbc 文件、终端电阻图纳入 Git,新人 10 分钟上手。


八、总结:一张脑图带走全部要点

瑞芯微 CAN 实时通信 ├─ 硬件:RK3568 M_CAN + TJA1057 ├─ 内核:PREEMPT_RT + hardirq + CPU 亲和 ├─ 配置:dts msg-ram + ip link fd on ├─ 测试:rt_send + cyclictest 抖动≤30 μs ├─ 容错:Bus-Off 自恢复≤110 ms └─ 文档:Git 管理 dbc + 电阻图 + 测试报告

实时性 + 国产化 + 工业级容错,一套方案同时搞定。
立刻拉出你的 RK3568 板子,复制本文设备树片段,重新编译烧录,用示波器抓一帧 CAN-FD 信号——你会亲眼看到:
国产芯 + 实时 Linux,一样能把时序做到微秒级!祝你调试顺利,产线永不掉帧。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/10 4:57:24

这份最新 AI / 机器学习学习路线!强烈建议收藏并反复阅读

当初决定踏入的 AI / 机器学习领域时&#xff0c;我感觉自己像是走进了一座没有地图的迷宫。四处寻找&#xff0c;满眼都是无穷无尽的教程、博客文章和训练营&#xff0c;个个都承诺能让你一夜成功。 但内心深处&#xff0c;我始终在问自己&#xff1a;我学的东西真的对吗&…

作者头像 李华
网站建设 2026/2/3 14:07:26

Win11 升级后 C 盘告急?Windows.old 文件清理攻略,一键释放几十 GB 空间

不少用户升级 Win11 最新版本后&#xff0c;都会发现 C 盘存储空间莫名缩水&#xff0c;打开文件夹查看才发现多了一个占用巨大的 Windows.old 文件。这个文件是系统升级时保留的旧版本安装文件&#xff0c;本意是方便后续回滚系统&#xff0c;但对大多数不需要降级的用户来说&…

作者头像 李华
网站建设 2026/2/14 22:04:07

【小程序毕设全套源码+文档】基于微信小程序的百货中心供应链管理系统设计与实现(丰富项目+远程调试+讲解+定制)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/2/3 16:03:22

HoRain云--TailwindCSS响应式设计实战指南

&#x1f3ac; HoRain云小助手&#xff1a;个人主页 &#x1f525; 个人专栏: 《Linux 系列教程》《c语言教程》 ⛺️生活的理想&#xff0c;就是为了理想的生活! ⛳️ 推荐 前些天发现了一个超棒的服务器购买网站&#xff0c;性价比超高&#xff0c;大内存超划算&#xff01;…

作者头像 李华
网站建设 2026/2/5 15:14:00

私域流量生态重构:链动2+1模式S2B2C商城小程序的流量整合与价值创造

摘要&#xff1a;在公域流量成本攀升与用户注意力碎片化的双重压力下&#xff0c;企业私域流量运营成为突破增长瓶颈的关键。本文以链动21模式S2B2C商城小程序为核心研究对象&#xff0c;结合电梯广告、社区场景等线下流量入口&#xff0c;构建"百川入海"的私域流量整…

作者头像 李华
网站建设 2026/2/8 21:06:48

燕尾潮汐表查询2026-02-03

位置&#xff1a;燕尾&#xff0c;日期&#xff1a;2026-02-03&#xff0c;农历&#xff1a;乙巳[蛇]年十二(腊)月十六&#xff0c;星期&#xff1a;星期二&#xff0c;潮汐类型&#xff1a;大潮活汛 最高水位&#xff1a;469.00cm&#xff0c;最低水位&#xff1a;59.00cm&a…

作者头像 李华