2026/4/18 7:20:30
网站建设
项目流程
绿色网站模版,做网站需要公司吗,建设集团摩托车,个人网站取域名一、简介#xff1a;为什么要在瑞芯微上“硬实时”驱动 CAN#xff1f;国产芯趋势#xff1a;瑞芯微 RK3568/RK3588 四核 A55A76#xff0c;自带 PCIe 2.1、USB3.0#xff0c;价格≅同行 1/2#xff0c;已被大量工业网关、机械臂控制器采用。实时痛点#xff1a;原生 Li…一、简介为什么要在瑞芯微上“硬实时”驱动 CAN国产芯趋势瑞芯微 RK3568/RK3588 四核 A55A76自带 PCIe 2.1、USB3.0价格≅同行 1/2已被大量工业网关、机械臂控制器采用。实时痛点原生 Linux CAN 驱动默认threaded interruptksoftirqd调度中断延迟 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 IPMessage RAMM_CAN 内部 FIFO减少 DMA 搬运每条 CAN 64 kBInterrupt Latency中断触发→ISR 第一条指令时间目标 ≤30 μsSocketCANLinux 标准 CAN 框架用户空间socket(AF_CAN,...)统一接口Fault Confinement错误计数器 96 警告255 总线关闭驱动自动快照三、环境准备10 分钟搭好开发机1. 硬件RK3568 工业核心板友善、-firefly、自画均可2×CAN-FD 收发器 TJA1057支持 5 MbpsUSB-CAN 卡PC 端做对比测试2. 软件组件版本获取瑞芯微官方 SDKv1.2.1GitHub 开源实时内核linux-5.15-rt47见下文一键脚本交叉工具链gcc-linaro-11.3官方预编译测试工具can-utils 2021.12.0apt install can-utils3. 一键打 RT 补丁可复制#!/bin/bash # rt_patch.sh VER5.15 RT_PATCHpatch-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 ARCHarm64 CROSS_COMPILEaarch64-linux-gnu- rockchip_linux_defconfig ./scripts/config -e CONFIG_PREEMPT_RT make ARCHarm64 CROSS_COMPILEaarch64-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_B5RX: 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 中断直接进入 hardirqRT 内核下可绑定到隔离核。5.3 中断 affinity CPU 隔离启动参数isolcpus1 nohz_full1 rcu_nocbs1 quiet splash把 CAN0 中断绑到 CPU0非隔离核保证 hardirqecho 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 can05.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 Mbpsdts 里 dbitrate 与采样点正确中断延迟 80 μs未关 threaded_irq驱动里改用devm_request_irqIRQF_NO_THREADcan0 up 后无数据终端电阻 120 Ω 未接CAN_H-CAN_L 间量电阻缺则并 120 Ω大量丢帧dmesg 报Rx FIFO overrun增大 Message RAM 长度或提高工作队列优先级热插拔节点后错误帧暴增线缆反射使用双绞屏蔽线屏蔽层单端接地七、实践建议与最佳实践中断隔离相机 DMA、网络 NIC 中断绑到非 RT 核避免抢占 CAN hardirq。提前计算采样点推荐数据段采样点 75%可用cancalc工具一键生成 dts 时序值。日志分级生产环境关闭can.debug打开can.err级别减少上下文切换。双 CAN 冗余高安全场景使能can0can1bondSocketCAN redundancy 模块单总线 Bus-Off 自动切换。产线老化测试48 h 连续 FD 帧 5 Mbps 打流错误帧 0.001% 视为通过。文档化把中断号、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一样能把时序做到微秒级祝你调试顺利产线永不掉帧。