版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、 CAN通信卡的Linux设备驱动程序设计实现 CAN通信卡的Linux设备驱动程序设计实现 类别:嵌入式系统  作者:清华大学自动化系(100084)杨 峰 吉吟东 薛 明
2、; 来源:电子技术应用 摘要:介绍了Linux下设备驱动程序的结构,描述了CAN通信卡设备驱动程序的软件框架以及如何将CAN设备驱动程序加入到Linux系统内核中。讨论了具体实现中为了提高通信效率和通信能力,改进设备驱动程序的缓冲区管理以及利用Linux的特点合理设计中断处理程序。
3、60; 关键词:Linux操作系统 设备驱动程序 CAN通信卡 中断处理程序 目
4、前,许多工业现场如电力系统、化工系统等大量使用控制器局部网(CAN-Controller Area Network)现场总线网络,CAN通信卡作为计算机的外设将计算机接入CAN网络。市场上有不少CAN通信卡,但基本上都不带Linux驱动程序,当需要在Linux下使用CAN通信卡设备时,需自己开发Linux的驱动程序。开发Linux驱动程序不但要求程序员要非常熟悉Linux系统,而且要熟悉Linux驱动程序开发的规范。本文将详细介绍CAN通信卡的Linux驱动设备程序的设计和实现。
5、0; 1 CAN通信卡的Linux设备驱动程序结构 Linux系统内核通过设备驱动程序与外围设备进行交互,设备驱动程序是Linux内核的一部分,它是一组数据结构和函数,这些数据结构和函数通过定义的接口控制一个或多个设备。对应用程序而言,设备驱动程序隐藏了设备的具体细节,对各种不同设备提供一致的接口,一般来说是把设备射为一个特殊的设备文件,用户程序可以象对普通文件一样对此设备文件进行操作。
6、; Linux将每个设备看作一个文件,即可以像对待文件那样使用read、write等系统调用进行读写。Linux的设备文件分为两类:一是字符设备,只能对该类设备进行顺序读写,对外提供字节流方式的操作;二是块设备,可以对该类设备进行随机访问,一般是磁盘设备等大容量存储设备。CAN通信卡设备属于字符型设备。 对设备的访问是由设备驱动程序提供的。Linux的设备驱动程序可以用模块的方式加载入内核,设备驱动程序与Linux系统的关系如图1所示。
7、0; 1.1 CAN通信卡设备的特点 控制器局部网(CAN)属于现场总线的范畴,它是一种有效支持分布式控制或实时控制的串行通信网络。由于其性能优异、价格低兼,很快被推广到工业测控现场。 CAN通信卡硬件实现CAN定义的物理层和数据链路层功能,收发报文中数据长度为08个字节,有2032个报文标识符。工作时通过报文标识符确定总线访问优先权,高优
8、先级报文具有低延迟时间,数据传送速率可编程(最高为1Mbps)。发送期间若丢二氧化碳仲裁或由于出错而破坏的报文可自动重发。具有成组和广播报文功能。 当CAN通信卡接收到一个报文时,数据保存在CAN通信卡上的接收缓存器中,并产生一接收中断。当一个报文被成功发关垢,发送缓冲器可再次被访问,产生一个发送中断信号。CAN通信卡发送报文,将数据送入CAN通信卡上的发送缓存器中,CAN通信卡将数据串行化发到CAN总线上。
9、;1.2 CAN通信卡设备驱动程序的任务 由于CAN一帧的数据长度最大为8个字节,可以用多帧的Hilon A协议来使CAN传输数据任意长。CAN通信卡驱动程序主要完成按照Hilon A协议解包接收和打包发送任务,并要对接收的多帧进行管理。
10、160; CAN通信卡驱动程序应该完成以下任务: (1)为应用程序提供通过CAN卡发送和接收任意长度数据的能力; (2)为应用程序提供设备CAN卡上CAN控制器运行参数的能力; (3)以阻塞或非阻塞方式读写CAN设备文件; &
11、#160;(4)允许CAN卡同时收发多路数据。 1.3 CAN通信卡驱动程序的处理流程 用户进程通过系统调用向驱动程序传送一帧任意长度的数据,驱动程序中发送数据的程序按照Hilon A协议将该帧分段打包,放入发送队列,并向CAN控制器请求发送,由中断处理程序中发送部分负责发送完所有的数据包。
12、 当CAN通信卡接收到数据时,产生接收中断,启动接收中断处理程序上半部将CAN控制器中接收缓冲器中的内容复制到接收队列中,由中断处理的下半部负责解包和组帧的任务,并将处理完的帧放入帧队列中,最后用户使用系统调用从接收帧队列中读取完整的一帧。 CAN通信卡设备驱动程序处理框架如图2所示。
13、60; 2 CAN通信卡设备驱动程序的模块化程序设计 根据Linux对设备驱动程序的要求,模块化的CAN驱动程序软件结构如图3。 2.1 初始化加载和卸载部分 如果设备驱动程序以模块方式加入内核,则一定会包括两个模块init_module和clear_module。init_modu
14、le模块用来加载设备,系统初始化时调用;clear_module模块用来卸载设备,取消设备时调用。 设备驱动程序是系统内核的一部分。在任何程序使用设备驱动程序之前,设备驱动程序应该向系统进行登记,以便系统在适当的时候调用。Linux系统里,通过调用register_chrdev函数向系统注册字符型设备驱动程序。Register_chrdev定义为: int register_chrdev(unsigned i
15、nt major,const char *name,struct file_operations *fops); 其中,major是为设备驱动程序向系统申请的主设备号,如果为0则系统为此驱动程序动态分配一个主设备号;name是设备名;fopsa是对各个系统调用的入口点的说明 。
16、 CAN通信卡使用中断与系统交换数据,CAN设备驱动程序需要使用内存来缓存接收到的数据和发送的数据,中断和内存等资源是由Linux系统统一管理的,设备驱动程序在初始化时,需要申请资源。在资源不用的时候,应该释放它们,以利于资源的共享。在Linux系统里,对中断的处理是属于系统核心的部分,设备驱动程序通过调用request_irq()函数来申请中断,通过free_irq()函数来释放中断。作为系统核心的一部分,设备驱动程序在申请和释放内存时不是调用malloc()函数和free()函数,而代之以调用kmalloc函数和kfree()函数。
17、 在init_module模块中,先检查是否存在CAN通信卡,如果不存在则退出设备驱动程序的加载;如果存在,使用request_irq()函数为CAN通信卡申请系统中空闲的中断,使用kmalloc()为设备驱动程序申请输入输出缓存队列,如果这些资源申请不成功,则释放已经申请到的系统资源,然后退出设备驱动程序的加载,如果申请成功,使用register_chrdev()函数将CAN通信卡驱动程序注册到Linux系统中,加载完成。
18、60; 在cleanup_module模块中先使用free_irq()函数释放init_module模块中申请到的中断,然后使用kfree()函数释放init_module模块中申请到的内存空间,最后使用unregister_chrdev()函数释放init_module模块中注册的设备驱动程序,卸载完成。
19、160; 2.2 CAN通信卡设备驱动程序的中断处理部分 Linux中断处理程序可以分为上半部和下半部。上半部即一般的中断服务程序,由硬件中断触发,它一般运行在关中断的方式下,应当尽可能短小,处理尽可能快;而下半部是单独的一段处理程序,一般将其挂入立即队列中以便快速执行。立即队列中的任务在退出系统调用或调度器获得
20、运行时,将最优先地被执行。下半部运行在一个安全的环境,即开中断和任务串行化,可以处理一些较花时间的任务。 这样,驱动程序上半部在处理完实时性很强的任务后,用queue_task()函数将下半部处理函数持入立即队列,并用mark_bh()函数来激活立即队列,则下半部可以最优先地被执行。 当有接收中断时,CAN通信卡设备驱动程序的中断处理程序上半部首先获取驱动程序接收缓存中的空闲块,将CAN通信卡上的接收缓冲器中
21、数据复制到驱动程序的接收缓存中,释放CAN通信卡接收缓冲器,然后将下半部处理函数挂入立即队列,最后激活立即队列。 当有发送中断时,CAN通信卡设备驱动程序的中断处理程序上半部首先获取发送缓冲队列中的数据,将需要发送的数据写入CAN控制器的发送缓冲器,最后请求发送。 CAN通信卡设备驱动程序的中断处理程序下半部使用Hilon &
22、#160;A协议对要传送到CAN网络上的数据打包,并对从CAN网络上接收到的数据进行解包和组帧。这样中断处理程序的上半部只需要从CAN通信卡的缓冲器中将数据复制到驱动程序的缓冲区,系统开销很小,但很费CPU时间;系统开销较大的打包、解包和组帧处理则放在中断处理程序的下半部,使用系统非中断时间调度,可以使系统响应中断更快,通信更稳定。 2.3 缓冲区管理 在CAN通信卡设备驱动程序中,为了增强CAN通信卡的通信
23、能力、提高通信效率,根据CAN的特点,使用两级缓冲区结构,即直接面向CAN通信卡的收发缓冲区和直接面向系统调用的接收帧缓冲区。 通讯中的收发缓冲区一般采用环形队列(或称为FIFO队列),使用环形的缓冲区可以使得读写并发执行,读进程和写进程可以采用“生产者和消费者”的模型来访问缓冲区,从而方便了缓存的使用和管理。然而,环形缓冲区的执行效率并不高,每读一个字节之前,需要判断缓冲区是否为空,并且移动尾指针时需要进行“折行处理”(即当指针指到缓冲区内存的末尾时,需要新将其定向到缓冲区的首地址);每写一个字节之
24、前,需要判断缓区是否为,并且移动尾指针时同样需要进行“折行处理”。程序大部分的执行过程都是在处理个别极端的情况。只有小部分在进行实际有效的操作。这就是软件工程中所谓的“8比2”关系。结合CAN通讯实际情况,在本设计中对环形队列进行了改进,可以较大地提高数据的收发效率。 由于CAN通信卡上接收和发送缓冲器每次只接收一帧CAN数据,而且根据CAN的通讯协议,CAN控制器的发送数据由1个字节的标识符、一个字节的RTR和DLC位及8个字节的数据区组成,共10个字节;接收缓冲器与之类似,也有10个字节的寄存器。
25、所以CAN控制器收的数据是短小的定长帧(数据可以不满8字节)。 于是,采用度为10字节的数据块业分配内存比较方便,即每次需要内存缓冲区时,直接分配10个字节,由于这10个字节的地址是线性的,故不需要进行“折行”处理。更重要的是,在向缓冲区中写数据时,只需要判断一次是否有空闲块并获取其块首指针就可以了,从而减少了重复性的条件判断,大大提高了程序的执行效率;同样在从缓冲队列中读取数据时,也是一次读取10字节的数据块,同样减少了重复性的条件判断。 &
26、#160; 在CAN卡驱动程序中采用如下所示的称为“Block_Ring_t”的数据结构作为收发数据的缓冲区: typedef struct log signature; unsigned char *head_p;
27、60; unsigned char *tail_p; unsigned char *begin_p; unsigned char *end_p; unsigned char buffer BLOCK_RING_BUFFER_SIZE; &
28、#160; int usedbytes; Block_Ring_t; 该数据结构在通用的环形队列上增加了一个数据成员usedbytes,它表示当前缓冲区中有多少字节的空间被占用了。使用usedbytes,可以比较方便地进行缓冲区满或空的判断。当usedbytes=0时,缓冲区空;当usedbytes=BLOCK_RING_BUFFER_SIZE时,缓冲区满。
29、60; 本驱动程序除了收发缓冲区外,还有一个接收帧缓冲区,接收帧队列负责管理经Hilon A协议解包后得到的数据帧。由于有可能要同接收多个数据帧,而根据CAN总线遥通信协议,高优先级的报文将抢占总线,则有可能在接收一个低优先级且被分为好几段发送的数据帧时,被一个优先级高的数据帧打断。这样会出现同时接收到多个数据帧中的数据包,因而需要有个接收队列对同时接收的数据帧进行管理。
30、 当有新的数据包到来时,应根据addr(通讯地址),mode(通讯方式),index(数据包的序号)来判断是否是新的数据帧。如果是,则开辟新的frame_node;否则如果已有相应的帧节点存地,则将数据附加到该帧的末尾;在插入数据的同时,应该检查接收包的序号是否正确,如不正确将丢弃这包数据。 每次建立新的frame_node时,需要向frame_queue申请内存空间;当frame_queue已满时,释放掉队首的节点(最早接收的但未完成的帧)并返回该节点的指针。
31、60; 当系统调用读取了接收帧后,释放该节点空间,使设备驱动程序可以重新使用该节点。 2.4 服务于I/O请求的设备驱动程序部分 这部分实际上是应用程序唯一可见的,应用程序通过系统来调用这部分程序,是设备驱动程序对应用程序的接口。本驱动程序提供文件操作接口。Linux系统中,字符型设备驱动程序提供的文件操作入口点由一个结构来向系统说明,此结构定义为:&
32、#160; struct file_operations int (*lseek)(strut inode *inode,struct file *file,off_toff,int pos); int (*read)(struct
33、 inode *inode,struct file *filp,char *buf,int count); int (*write)(struct inode *inode,struct file *file,char *buf,int count); &
34、#160; int (*readdir)(struct inode *inode,struct file *filp,struct dirent *dirent,int count); int (*select)(struct inode *inode,struct file *filp,i
35、nt sel_type,select_table *wait); int (*ioctl)(struct inode *inode,struct file *filp,unsigned int cmd,unsigned int arg); int (*mmap)(void);
36、160; int (*open)(struct inode *inode,struct file *filp); void (*release)(struct inode *inode,struct file filp);int (fsync) (struct inode *inode,struct file *filp); &
37、#160; ; 该结构定义为10个操作入口点,但是驱动程序没有必要对每个入口点进行定义。根据需要,本驱动程序定义了如下的入口点。 can_open(struct inode *inode,struct file *filp)入口点负责打开can设备,检查can卡是否已被打开,完成can卡的初始化,设备设备的占用标志。can_release(struct
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 化疗静脉通路选择与护理指导
- 深度解析(2026)《GBT 35890-2018高通量测序数据序列格式规范》
- 深度解析(2026)《GBT 35476-2017罗汉果质量等级》
- 深度解析(2026)《GBT 35420-2017物联网标识体系 Ecode在二维码中的存储》
- 《DLT 1086-2022光电式CCD静力水准仪》从合规成本到利润增长全案:避坑防控+降本增效+商业壁垒构建
- 汽车理论试题及答案
- 学校防欺凌工作制度
- 陶瓷艺术试题及详解
- 执业药剂师题库及答案
- 眼科青光眼治疗试题及解析
- 2026年抗菌药物考试题及答案
- 2026年山东省夏季高考《语文》作文专项练习及答案解析(全国I卷)
- 四川省成都市 2026 届高三第三次诊断性考试试题(含答案)
- 2018年上半年全国事业单位联考D类《职业能力倾向测验》答案+解析
- 2026年北京市平谷区初三下学期一模道德与法治试卷和答案
- 2026年广东广州市高三二模高考数学试卷试题(含答案详解)
- 广播安装施工方案(3篇)
- 特医食品管理工作制度
- 人教版五年级数学下册第三单元《长方体与正方体的表面积》专项训练(含答案)
- 2025年四川省达州市中考物理模拟试题(试卷+解析)
- 国开2026年《新媒体伦理与法规》形成性考核1-5答案
评论
0/150
提交评论