“插座”,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);

  • 利用readwrite发CAN报文:                  

         read(s, &frame, sizeof(structcan_frame))

         或

         write(s, &frame, sizeof(struct can_frame)) 

  • 如需要,可关闭前述套接字:close(s)。




以上是关于“插座”,SocketCAN怎么用?的主要内容,如果未能解决你的问题,请参考以下文章

基于java的socket简单聊天编程

Linux SocketCan client server demo hacking

socket can 编程

Socket CAN

用Socket开发一枚小型实时通信App

我可以强制冲洗 CAN 总线插座吗