基于Can总线的嵌入式网络控制节点的设计与实现
在,许多ARM生产厂商都已经将Linux系统移植到其生产的ARM芯片上,并发布了相关源代码供用户免费使用。本系统中采用的操作系统就是ATMEL公司发布的支持其AT912RM9200处理器的ARM-Linux系统的版本,版本号为2.4.27。
CAN控制器SJA1000显然属于Linux系统中的字符设备类型,其驱动程序的实现架构类似于系统中字符设备的通用实现结构,关于Linux设备驱动开发的详细分析可参考文献。本小节则以SJA1000的增强工作模式(PeIiCAN)为例,对Linux系统下CAN设备驱动程序的主要实现部分进行了详细说明,包括主要数据结构的定义、操作函数和中断函数的实现三个部分。
2.1 CAN设备驱动的主要数据结构
为方便驱动程序的设计和编写,驱动中定义了两个数据结构体,即协议帧数据结构和缓冲区结构体,下面给出每个结构体的定义及成员变量的解释。
其中,协议帧结构体是用来对CAN网络的报文数据帧进行抽象,驱动中使用该结构体来进行用户与内核空间的数据帧传递及发送/接收数据缓冲区的管理。
从缓冲区结构体的定义可以看出,CAN设备的数据缓冲区由两个独立缓冲区构成,一个用于设备读操作,另一个用于写操作。读缓冲区和写缓冲区都是一个先入先出的环形缓冲区,缓冲区的大小设为协议帧结构体的整数倍,如64倍。驱动通过缓冲区的读指针和写指针来进行缓冲区管理。如对于接收缓冲区(读缓冲区),它的读指针指向了当驱动程序从内核空间向用户空间拷贝报文数据帧时,缓冲区中第一个有效数据帧的位置;而缓冲区的写指针则代表了在控制器芯片执行接收数据时,即将数据帧从SJA1000的寄存器读到缓冲区,缓冲区的当前可写位置;这样通过读指针和写指针的相对位置及缓冲区的整体长度就可以得到读缓冲区中当前的数据帧个数。写缓冲区的管理与读缓冲区基本相同,其详细机制可参考后面给出的相关伪代码。同时缓冲区中还定义了volatile int型变量tx_in_progress来表征当前是否有实际的数据发送操作已被启动,“1”标识已启动,否则为“0”。另外,结构体定义中使用到了Linux系统的等待队列结构,关于它的详细机制可参考文献。
2.2 CAN设备的操作函数
字符设备驱动的核心就是实现设备的操作函数结构,所谓的操作函数结构,本质上是定义了应用程序在设备上的所有可能操作。但对于某一具体设备,驱动中只需要实现设备工作所必须的操作。如对于CAN设备,本例中共实现了5种系统调用函数,即open, close, read, write和ioctl函数。
其中,open函数是在应用程序打开CAN设备时被调用,函数主要实现两部分功能,首先对驱动中的变量和数据结构进行初始化,并分配缓冲区空间。另一部分就是对CAN控制器SJA 1000初始化,即在复位时为芯片的各个寄存器设置正确的初始值。对于SJA1000芯片,需要设置的寄存器包括:1)模式和时钟寄存器;2)输出控制寄存器;3)验收代码寄存器和验收屏蔽寄存器;4)总线定时寄存器;5)错误计数寄存器;6)中断使能寄存器。需要注意的是,SJA1000的配置寄存器只能在复位模式下可写,所以在设置寄存器之前,必须先进入复位模式,所有设置完成后必须返回正常工作模式,关于SJA 1000芯片寄存器设置的更多内容可参见文献。CAN设备的close调用的实现功能非常简单,即等待缓冲区中已有的数据帧被处理完,然后释放缓冲区,最后关闭设备中断。
驱动程序的write就是对应于用户写CAN设备时的系统调用。它的功能就是完成应用程序在用户空间中的报文发送,即报文数据从用户空间向内核空间的传递。下面给出了实现write函数的伪代码:
ssize t can-write(......)
{
.....
判断指定的数据长度是否满足数据帧格式,若不满足,则提示并返回;
通过写指针和读指针的相对位置及缓冲区的整体长度计算输出缓冲区中空闲空间的大小,
while空闲空间长度<一个数据帧大小使用interruptible_sleep_on_timeout()函数将写进程放入写操作等待队列睡眠,该函数既说明了睡眠可被信号中断,还可以指定进程的最长睡眠时间;
睡眠结束后,再次计算空闲空间的大小。若空闲空间长度已大于或等于一个数据帧大小,则可跳出循环,否则继续while循环;
从用户空间拷贝N字节数据到输出缓冲区,其中:N = min(计算的空闲空间大小,数据长度参数),然后更新输出缓冲区的写指针位置;
if当前无实际的发送操作已被启动,即tx_in_progress等于0
置位tx in_progress为1,同时调用发送初始化函数,即将输出缓冲区中第一个有效数据帧写入到控制器芯片相应的发送寄存器中,同时使能发送操作,完成后,结束c} write()函数并返回数值N;
else
函数直接结束,返回N
}
需要说
Can总线网络控制节 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)