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μs
CPU占用率 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.39 Linux 3.0
SocketCAN 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. 故障排查指南

常见问题及解决

  1. 设备无法启动

    • 检查内核模块是否加载:lsmod | grep can
    • 确认硬件驱动支持:dmesg | grep can
  2. 接收不到数据

    • 检查过滤设置:ip -det link show can0
    • 确认总线速率匹配:ip -d link show can0
  3. 高错误率

    • 检查物理连接:终端电阻、线缆质量
    • 使用candump -e can0查看错误帧

10. 参考资料

posted @ 2026-06-29 15:46  Jaosn_chen  阅读(8)  评论(0)    收藏  举报