美文网首页
linux 中在命令行中使用 SocketCAN(以 PCAN

linux 中在命令行中使用 SocketCAN(以 PCAN

作者: 刘亚彬92 | 来源:发表于2020-06-08 08:48 被阅读0次

    1 什么是 SocketCAN

    根据 维基百科 的介绍,SocketCAN 是一个开源的 CAN 驱动以及网络堆栈。在 linux 中,传统的 CAN 驱动是基于字符设备(character device)模型的。一个典型的设备驱动实现,只允许一个进程访问一个设备,其他进程的访问会被阻塞。而且不同设备之间的驱动往往略有不同,这也给移植带来了不便。而 SocketCAN 使用了网络设备模型,允许多个应用同时访问同一个 CAN 设备,而一个应用也可以同时访问多个 CAN 总线。

    Linux 内核中在 2.6.25 版本中加入了 CAN 的补丁,同时也添加了一些 CAN 设备的驱动。这里所用到的 PCAN 驱动基本上主流的 linux 发布版也都支持。

    2 什么是 PCAN

    PCAN 是一个 CAN 转 USB 的设备,由德国 PEAK-System 公司生产。一般一端用来连接 CAN 总线另一端用来连接 USB 主机(工控机、ECU、PC等)。这个东西还是比较贵的,差不多要 2k 多 RMB。有人可能就有疑问了,不就是一个 CAN 转 USB 吗?某宝上随便一搜也就是2百多块。为啥这个这么贵?下面我就简单的总结一下 PCAN 的优势:

    • PCAN 广泛运用到汽车领域,应该是车规级的产品(我没有查到相关的资料,只是凭感觉推断)。
    • PCAN 支持 windows、linux 系统、以及 linux 实时扩展 Xenomai,RTAI (对应为“实时驱动模式”)。
    • PCAN 支持 C++、Java、Python 3.x 等编程语言甚至可以直接将数据输入到 matlab/simulink 车辆网络工具箱。
    • Qt 也自带对该设备的支持(通过 Qt CAN Bus)。
    • 支持 CAN 2.0 a/b 协议以及 CAN FD 协议[1]
    • 读取数据支持事件触发[2]
    • 各种各样的软件以及成熟的生态。尤其是在汽车通信领域。
    • 等等。

    [1] CAN FD 协议:全称为 Controller Area Network Flexible Data-Rate. 是对原有 CAN 协议的一种扩展。在 2011 年开发并于 2012 年由博世(Bosch)公司发布。和传统 CAN 协议不同,主要体现在了灵活数据(Flexible Data)。主控单元可以动态的切换不同的数据频率(允许高达传统 CAN 传输速率5倍的速度传输),而且每一帧的数据负载大小由最多8字节提升到64字节。

    [2] 这一点很容易被其他的 USB-CAN 设备厂商忽略。我在某宝上买过2百多块的 USB-CAN 设备。当时我问老板支不支持事件触发,老板说:“不支持,而且目前国内所有的厂商都不支持。”(这篇文章写于2020年6月5日)。也就是说,使用这些设备你只能使用查询的方式读取数据,这就基本不可能保证实时性。专门使用一个线程开启事件循环来查询接收缓冲区也会浪费大量的 CPU 资源。因此这些设备配套的软件基本无法打到工业级标准,即使他们的硬件达到了标准。

    需要注意的是如果你使用的 PCAN 已经安装了对应的字符设备驱动(chardev),那么是无法使用 SocketCAN 的,如果需要使用 SocketCAN(即网络驱动 aka netdev),需要你根据 PCAN 用户手册重新安装网络驱动。如果你的电脑上没有安装任何关于 PCAN 的驱动,那么默认是可以使用下面的 SocketCAN 的。

    3 如何在 Linux 命令行中使用 SocketCAN

    终于进入正题了。这部分内容主要来自于 How To Use SocketCAN With The Command-Line In Linux。我的环境如下:

    • USB-CAN 设备为 PCAN。
    • 系统为状态 VMware 中的 Ubuntu 16.04。

    3.1 SocketCAN 提供了哪些 CAN 接口类型?

    • Native interfaces: 本地接口对应了真实的硬件(如 USB-CAN 适配器),这些接口命名为 canX,如 can0, can1,...
    • Virtual interfaces: 虚拟接口并没有对应实际的硬件,它们被命名为 vcanX,如 vcan0, vcan1,...
    • SLCAN based interfaces: 基于 SLCAN 的接口提供了串行接口,它们被命名为 slcanX,如 slcan0, slcan1,等等。

    3.2 列出 SocketCAN 接口

    在连接好设备之后,我们首先可能想做的就是查看本地都有哪些 CAN 接口(设备是否被正确识别):

    $ ip link show
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
        link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
        link/ether 00:0c:29:97:9a:46 brd ff:ff:ff:ff:ff:ff
    3: can0: <NOARP,ECHO> mtu 16 qdisc noop state DOWN mode DEFAULT group default qlen 10
        link/can
    

    这里的最后一个接口 can0 就是 SocketCAN 接口。此时你可能还希望打印本地支持 SocketCAN 的 CAN 设备信息:

    $ ip addr ls dev can0
    3: can0: <NOARP,ECHO> mtu 16 qdisc noop state DOWN group default qlen 10
        link/can
    $ ip addr ls dev can1  # 尝试不存在的设备
    Device "can1" does not exist.
    

    另一种显示 CAN 接口信息的方法是使用 ifconfig <canx>:

    $ ifconfig can0
    can0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
              NOARP  MTU:16  Metric:1
              RX packets:0 errors:0 dropped:0 overruns:0 frame:0
              TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:10
              RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
    

    3.3 配置并且使能 SocketCAN 接口

    对于实际存在的 CAN 设备(连上设备时自动创建的 can0),可以使用如下的方法设定波特率(这里为 1M):

    sudo ip link set can0 type can bitrate 1000000
    

    如果你使用的是虚拟 CAN 接口,会略有不同:

    $ sudo modprobe vcan
    $ sudo ip link add dev vcan0 type vcan
    

    使能 SocketCAN 接口使用如下的命令:

    $ sudo ip link set up can0
    

    如果出现 RTNETLINK answers: Operation not supported 错误,去先尝试执行 sudo modprobe can 或者 sudo modprobe vcan

    3.4 使用 SocketCAN 发送或者接受数据

    首先需要安装 can-utils:

    $ sudo apt install can-utils
    

    如果你的设备连接到了其他的 CAN 设备,你可以使用如下的命令来发送数据到该设备:

    $ cansend can0 123#1122334455667788
    

    其中 123 为 id 表示 0x123,数据为 [ 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 ]。注意值总是被认为是16进制。

    如果希望显示所有接收到的消息,可以使用如下命令:

    $ candump can0
    

    相关文章:

    How To Use SocketCAN With C++ In Linux

    相关文章

      网友评论

          本文标题:linux 中在命令行中使用 SocketCAN(以 PCAN

          本文链接:https://www.haomeiwen.com/subject/bmgazhtx.html