Linux内核Socket CAN中文文档
Linux内核Socket CAN中文文档分类: 嵌入式 内核驱动2012-06-08 20:36 3711人阅读 评论(1) 收藏 举报socketlinux内核网络structfilterlinux自己在年假中空闲之余翻译的内核中Socket CAN的文档,原文地址在:/linux+v2.6.34/Documentation/但是这篇文档没有涉及广播管理协议套接字 (SOCK_DGRAM) 的内容。另外一篇比较好的Socket CAN的英文文档是(详细介绍了广播管理协议套接字):Low Level CAN Framework Application Programmers Interface/docs/socketcan/llcf-api.html#SECTION00051000000000000000自己暂时没时间翻译这篇文章了,有空再说吧。 自己英文水平有限,希望高人指正。================================================================================ 这篇文章主要针对can协议簇(aka socket can)这篇文章包含以下内容:===============1 概述--什么是Socket CAN?
2 动机--为什么使用socket API接口?
3 Socket CAN详解 3.1 接收队列 3.2 发送帧的本地回环 3.3 网络安全相关 3.4 网络故
障监测
4 如何使用Socket CAN 4.1 使用can_filter的原始套接字 (RAW socket) 4.1.1 原始套接字选项 CAN_RAW_FILTER 4.1.2 原始套接字选项 CAN_RAW_ERR_FILTER 4.1.3 原始套接字选项 CAN_RAW_LOOPBACK 4.1.4 原始套接字选项 CAN_RAW_RECV_OWN_MSGS 4.2 广播管理协议套接字 (SOCK_DGRAM) 4.3 面向连接的传输协议 (SOCK_SEQPACKET) 4.4 无连接的传输协议 (SOCK_DGRAM)
5 Socket CAN核心模块 5.1 can.ko模块的参数 5.2 procfs接口 5.3 写一个自己的CAN协议模块
6 CAN网络驱动 6.1 常见设置 6.2 发送帧的本地回环 6.3 CAN控制器的硬件过滤 6.4 虚拟的CAN驱动 (vcan) 6.5 CAN网络设备驱动接口 6.5.1 Netlink接口--设置/获取设备属性 6.5.2 设置CAN的比特_时序 6.5.3 启动和停止CAN网络设备 6.6 支持Socket CAN的硬件
7 学习Socket CAN的相关资源
linux中文名
8 贡献者名单
==============现在开始===================1. 概述--什么是Socket CAN?==================
socketcan子系统是在Linux下CAN协议(Controller Area Network)实现的一种实现方法。 CAN是一种在世界范围内广泛用于自动控制、嵌入式设备和汽车领域的网络技术。Linux下最早使用CAN的方法是基于字符设备来实现的,与之不同的是Socket CAN使用伯克利的socket接口和linux网络协议栈,这种方法使得can设备驱动可以通过网络接口来调用。Socket CAN的接口被设计的尽量接近TCP/IP的协议,让那些熟悉网络编程的程序员能够比较容易的学习和使用。
2. 动机--为什么使用socket API接口?=======================
在Socket CAN之前Linux中已经有了一些CAN的实现方法,那为什么还要启动Socket CAN这个项目呢?大多数已经存在的实现方法仅仅作为某个具体硬件的设备驱动,它们往往基于字符设备并且提供的功能很少。那些方案通常是由一个针对具体硬件的设备驱动提供的字符设
备接口来实现原始can帧的发送和接收,并且直接和控制器硬件打交道。帧队列和ISO-TP这样的高层协议必须在用户空间来实现。就像串口设备接口一样,大多数基于字符设备的实现在同一时刻仅仅支持一个进程的访问。如果更换了CAN控制器,那么同时也要更换另一个设备驱动,并且需要大多数应用程序重新调整以适应新驱动的API。
Socket CAN被设计用来克服以上种种不足。这种新的协议族实现了用户空间的socket接口,它构建于Linux网络层之上,因此可以直接使用已有的队列功能。CAN控制器的设备驱动将自己作为一个网络设备注册进Linux的网络层,CAN控制器收到的CAN帧可以传输给高层的网络协议和CAN协议族,反之,发送的帧也会通过高层给CAN控制器。传输协议模块可以使用协议族提供的接口注册自己,所以可以动态的加载和卸载多个传输协议。事实上,CAN核心模块不提供任何协议,也不能在没有加载其它协议的情况下单独使用。同一时间可以在相同或者不同的协议上打开多个套接字,可以在相同或者不同的CAN ID上同时监听和发送(listen/send)。几个同时监听具有相同ID帧的套接字可以在匹配的帧到来后接收到相同的内容。如果一个应用程序希望使用一个特殊的协议(比如ISO-TP)进行通信,只要在打开套接字的时候选择那个协议就可以了,接下来就可以读取和写入应用数据流了,根本无需关心CAN-ID和帧的结构等信息。使用字符设备也可以让用户空间获得类似的便利,但是这中解
决方案在技术上不够优雅,原因如下:
*复杂的操作。使用Socket CAN,只需要向socket(2)函数传递协议参数并使用bind(2)选择CAN接口和CAN ID,基于字符设备实现这样的功能却要使用ioctl(2)来完成所有的操作。
*无法代码复用。字符设备无法使用Linux的网络队列代码,所以必须为CAN 网络重写这部分功能。
*缺乏抽象性。在大多数已经实现的字符设备方案中,硬件相关的CAN控制器设备驱动直接提供应用程序需要的字符设备。在Unix系统中,无论对于字符设备还是块设备,这都是不常见的。比如,你不会为某个串口、电脑上的某个声卡、访问磁带和硬盘的SCSI/IDE控制器直接创建一个字符设备。相反,你会将向应用程序提供统一字符设备/块设备接口的功能交给一个抽象层来做,你自己仅仅提供硬件相关的设备驱动接口。这种抽象是通过子系统来完成的,比如tty层子系统、声卡子系统和SCSI/IDE子系统。
实现CAN设备驱动最简单的办法就是直接提供一个字符设备而不使用(或不完全使用)抽象层,大多数已经存在的驱动也是这么做的。但是正确的方法却要增加抽象层以支持各种功能,
如注册一个特定的CAN-ID,支持多次打开的操作和这些操作之间的CAN帧复用,支持CAN帧复杂的队列功能,还要提供注册设备驱动的API。然而使用Linux内核提供的网络框架将会大大简化,这就是Socket CAN要做的。
在Linux中实现CAN功能最自然和合适的方式就是使用内核的网络框架。
3. Socket CAN详解============
就像第二章所讲的那样,使用Socket CAN的主要目的就是为用户空间的应用程序提供基于Linux网络层的套接字接口。与广为人知的TCP/IP协议以及以太网不同,CAN总线没有类似以太网的MAC层地址,只能用于广播。CAN ID仅仅用来进行总线的仲裁。因此CAN ID在总线上必须是唯一的。当设计一个CAN-ECU(Electronic Control Unit 电子控制单元)网络的时候,CAN-ID可以映射到具体的ECU。因此CAN-ID可以当作发送源的地址来使用。
3.1 接收队列---------------
允许多个应用程序同时访问网络导致了新的问题出现,那就是不同的应用程序可能会在同一个CAN网络接口上对具有相同CAN-ID的帧感兴趣。Socket CAN的核心部分实现了Socket C
AN的协议族,通过高效的接收队列解决了这个问题。比如一个用户空间的程序打开了一个原始CAN套接字,原始协议模块将向CAN套接字的核心模块申请用户空间需要的一系列CAN-ID。Socket CAN的核心向CAN协议模块提供预约和解约CAN-ID的接口--can_rx_(un)register(),无论这个CAN-ID是针对一个具体的CAN接口还是所有已知的CAN接口(参考第5章)。
为了优化CPU的运行效率,每个设备都对应一个接收队列,这样比较容易实现各种报文过滤规则。3.2 发送帧的本地回环
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论