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

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,639评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,277评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,221评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,474评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,570评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,816评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,957评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,718评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,176评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,511评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,646评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,322评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,934评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,755评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,987评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,358评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,514评论 2 348