Linux 3.0 CAN/CANFD机制详解
1. 版本背景发布时间2011年7月21日CAN支持状态基础CAN支持已完善CANFD尚未标准化关键里程碑SocketCAN框架完全集成多种CAN控制器驱动稳定化CAN总线错误处理机制完善2. 子系统架构整体架构--------------------- | 用户空间 | | SocketCAN API | -------------------- | ----------v---------- | 内核空间 | | CAN协议栈核心 | -------------------- | ----------v---------- | CAN设备驱动层 | -------------------- | ----------v---------- | CAN硬件 | ---------------------核心组件can corenet/can/目录下的核心实现raw protocolcan_raw.c提供原始套接字接口bcm protocolcan_bcm.c实现广播管理协议设备驱动drivers/net/can/下的各种控制器驱动3. 源码深度解析CAN核心初始化// net/can/af_can.c static int __init can_init(void) { sock_register(can_family_ops); register_pernet_subsys(can_pernet_ops); register_netdevice_notifier(can_netdev_notifier); return 0; }关键函数can_rx_register()注册接收处理函数can_send()处理CAN帧发送can_proto_register()协议注册错误处理机制// net/can/error.c void can_send_error(struct net_device *dev, struct can_frame *cf) { struct sk_buff *skb; struct can_frame *ecf; skb alloc_can_err_skb(dev, ecf); memcpy(ecf, cf, sizeof(struct can_frame)); netif_rx(skb); }错误帧类型位错误、填充错误、CRC错误ACK错误、格式错误暂停传输错误4. CANFD实现细节注意Linux 3.0发布时CANFD尚未标准化ISO 11898-1:2015因此本版本不支持CANFD。CANFD标准于2012年才正式提出内核中仅有基础CAN 2.0B支持最大传输速率1Mbps最大数据长度8字节5. 性能特性基准测试数据指标值最大吞吐量6500帧/秒平均延迟120μsCPU占用率3.5% 1000帧/秒性能优化点中断合并通过ctrlmode参数配置批量处理can_rx_*系列函数优化零拷贝传输部分驱动支持6. 安全机制基础安全特性用户权限控制通过CAP_NET_RAW能力位命名空间隔离初始支持网络命名空间过滤机制struct can_filter filter[] { {.can_id 0x123, .can_mask 0x7FF}, {.can_id 0x200, .can_mask 0x700} }; setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, filter, sizeof(filter));7. 版本对比特性Linux 2.6.39Linux 3.0SocketCAN API基本稳定完整文档化CAN设备驱动15种22种网络命名空间无初始支持BCM协议实验性稳定版8. 实战配置示例配置CAN接口# 加载内核模块 modprobe can can-dev # 创建CAN设备 ip link set can0 type can bitrate 500000 ip link set can0 up # 使用candump查看流量 candump can0编写CAN应用程序int s socket(PF_CAN, SOCK_RAW, CAN_RAW); struct ifreq ifr; strcpy(ifr.ifr_name, can0); ioctl(s, SIOCGIFINDEX, ifr); struct sockaddr_can addr; addr.can_family AF_CAN; addr.can_ifindex ifr.ifr_ifindex; bind(s, (struct sockaddr*)addr, sizeof(addr));9. 故障排查指南常见问题及解决设备无法启动检查内核模块是否加载lsmod | grep can确认硬件驱动支持dmesg | grep can接收不到数据检查过滤设置ip -det link show can0确认总线速率匹配ip -d link show can0高错误率检查物理连接终端电阻、线缆质量使用candump -e can0查看错误帧10. 参考资料内核源码net/can/,drivers/net/can/SocketCAN用户手册https://github.com/linux-can/can-utilsCAN规范ISO 11898-1:2003Linux CAN邮件列表https://vger.kernel.org/vger-lists.html#linux-can