“插座”,SocketCAN怎么用?
Posted CatchCAN
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了“插座”,SocketCAN怎么用?相关的知识,希望对你有一定的参考价值。
SocketCAN是Linux环境下的一种CAN协议实现方法,最早由大众汽车提供给Linux内核。如今,在2.6.25及之后版本的Linux内核中默认集成了SocketCAN。Python3.3也增加了对SocketCAN的支持。
在SocketCAN出现之前,Linux环境下实现对CAN的访问都是基于字符设备,不同厂家的硬件其驱动都是不一样的。SocketCAN将CAN当做一个网络设备(见图1),增加了一个协议族PF_CAN,将CAN的访问变成类似于网络接口的方式,屏蔽了底层硬件的不同,使应用层对CAN网络的访问实现了接口统一。
图1 SocketCAN的架构
SocketCAN(netdev)与基于字符(chardev)的CAN访问方式,在使用上有如下显著差异:
SocketCAN允许同一时间有多个应用可以访问同一个CAN设备,而基于字符的方式同一时间只允许唯一一个应用可以访问CAN设备。
SocketCAN自身可设置过滤机制及高层CAN协议,而基于字符的方式下这些只能交给应用去完成。
图2展示了SocketCAN(netdev)和基于字符的CAN(chardev)驱动之间的分层差异。
图2 netdev和chardev的分层差异
SocketCAN的缺点也是很明显的:
内存开销大,因为linux的网络接口一开始是为长数据帧的以太网准备的,而CAN只有8字节的数据场;
Packet scheduler是各接口共用的,所以在有大数据量的以太网通讯时,会导致CAN通讯的延误;
不支持硬件过滤机制。
以Ubuntu14.04为例,接入PEAK的USB2CAN,波特率250kbps,使用SocketCAN进行CAN通信有如下步骤:
首先,SocketCAN无需安装,已经集成在这个版本中;
其次,考虑测试的方便性,建议安装can-utils;
再其次,配置并启动CAN:
$sudo ip link set can0 type can bitrate 250000
$sudo ifconfig can0 up
再再然后,就可以用前面讲到的can-utils工具收发报文,或者编写程序代码执行相关的CAN收发任务了。
具体到程序代码的编写,其主要包含如下几个部分:
建立一个SocketCAN套接字:
s=socket(PF_CAN, SOCK_RAW, CAN_RAW);
获取前述套接字对应的索引:
ioctl(s, SIOCGIFINDEX,&ifr);
绑定套接字和对应的接口:
bind(s, (struct sockaddr*)&addr, sizeof(addr));
如需要,可设定过滤机制:
setsockopt(s, SOL_CAN_RAW,CAN_RAW_FILTER, &rfilter, sizeof(rfilter));
注:关闭则可用setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, NULL, 0);
利用read或write收发CAN报文:
read(s, &frame, sizeof(structcan_frame))
或
write(s, &frame, sizeof(struct can_frame)) 。
如需要,可关闭前述套接字:close(s)。
以上是关于“插座”,SocketCAN怎么用?的主要内容,如果未能解决你的问题,请参考以下文章