由于CAN总线的高性能和可靠性,所以被广泛地应用于工业自动化、船舶、医疗设备、工业设备等方面。而目前多数嵌入式处理器都不带CAN总线控制器,本文基于深圳恒天智信科技公司的GT2440开发板和MSG-3CM型CAN总线模块开发板,在linux操作系统环境下,详细介绍了开发CAN总线设备驱动程序的方法与过程。
GT2440是一款具有极高性价比的嵌入式开发系统,CPU处理器采用Samsung S3C2440A,主频400MHz;板载64M SDRAM、256M Nand Flash、2 M Nor Flash;板载5线异步串行口(UART0)、10M以太网RJ-45接口、USB HOST接口、USB Slave B型接口和一个SD卡存储接口;集成了4线电阻式触摸屏接口和JTAG接口等。
S3C2440A是由三星公司推出的16/32位RISC微处理器,最高主频可达533MHz,处理器内部集成SDRAM控制器、LCD控制器、4通道DMA、3通道UART、I2C总线接口、I2S音频编解码器接口、SD接口、2路SPI接口、8通道10位A/D控制器和camera接口等。
CAN通信电路主要由CAN控制器和CAN收发器组成,本文采用的是MSG-3CM型CAN总线模块开发板,其原理图如图1所示。图中13~16引脚连着CPU,其余的除了INT和中断相关之外,都连着TJA1050收发器。
MSG-3CM型CAN总线模块开发板的控制芯片是MICROCHIP公司的MCP2515[1],MCP2515是Microchip Technology Inc.(美国微芯科技有限公司)生产的一款控制局域网络(CAN)协议的控制器,完全支持CAN总线V2.0A/B技术规范;能够发送和接收标准和扩展报文。它还同时具备验收过滤以及报文管理功能;该器件包含三个发送缓冲器和两个接收缓冲器。其与GT2440开发板的通讯是通过行业标准串行外设接口(SPI)来实现的,其数据传输速率高达5Mb/s。
TJA1050作为CAN总线收发器芯片,提供了CAN控制器与物理总线之间的接口,有对CAN总线的差动发送和接受功能[2]。当CAN控制器要从TJA1050接受一个数据时,首先RXnBF信号必须有效(为低电平),然后TJA1050收发器将数据通过RXCAN引脚传入到对应的第n+1个缓冲区;同理,当CAN控制器要发送数据给TJA1050时,TXnRTS信号必须有效(为低电平),然后控制器将第n+1个缓冲区的数据通过TXCAN引脚传入到收发器TJA1050。
搭建开发环境的过程为:
(1)在Win7系统下安装虚拟机vmware6.0,在虚拟机里安装RHEL5操作系统。在RHEL5操作系统下用交叉编译工具编译开发板所需的镜像和文件,使用Samba服务器实现了Win7和RHEL5的文件共享,在Win7系统下可以通过串口或USB直接下载镜像和文件到GT2440开发板上。
(2)由于win7系统不带超级终端,所以串口终端使用的是SecureCRT5.5软件,SecureCRT是一款支持SSH(SSH1和SSH2)的终端仿真程序,同时支持Telnet和rlogin协议,SecureCRT是一款用于连接运行包括Windows、UNIX和VMS的远程系统的理想工具。笔记本电脑和开发板之间使用USB转串口线连接,这样就可以在笔记本电脑上对开发板进行开发操作。
本设计使用的bootloader是深圳恒天智信科技公司自己开发的u-boot,用J-LINK V8仿真器连接好开发板和笔记本电脑,打开j-flash进行相关的配置,然后将u-boot烧写进NOR Flash,然后重启就可以在secureCRT串口终端打印出u-boot相关信息,根据提示就可以进行下载操作了。从官方网站上下载Linux2.6.38内核源代码,通过Samba服务器将源代码复制到RHEL5操作系统共享目录下,使用tar命令解压到/opt目录。在/opt/linux-2.6.38.6/目录下使用交叉编译工具对内核进行修改、配置和编译。在移植CAN总线驱动之前,需要移植板载256M NAND Flash的驱动、yaffs2文件系统等。
Linux系统设备[3]分为三种基本类型:字符设备、块设备、网络设备。CAN总线属于字符设备,是个能够像字节流(类似文件)一样被访问的设备。在Linux系统中,以文件名的形式在/dev目录下建立CAN总线设备文件,应用程序可以通过系统调用函数open()打开此文件,建立起与设备的连接,然后通过函数read()、write()、release()、ioctl()等函数调用对目标设备进行操作。内核是通过主设备号将设备驱动程序和设备文件相连的,而构成驱动程序的一个重要数据结构就是file_operations,内核就是通过这个结构来访问驱动程序的。file_operations中的成员为一系列指向各操作函数的指针,这些操作函数主要负责系统调用的实现,不同类型的设备文件系统有不同类型file_operations结构。
CAN总线的file_operations结构[4]定义为:
图1 MSG-3CM型CAN总线模块开发板原理图
根据CAN通信协议和系统应用的需要,在驱动程序中定义了CanData的数据结构以传输数据,结构如下:
根据需要定义一个Mcp2515_DEV的数据结构,用于记录接收缓冲区运行的各种状态:
定义并初始化完成file_operations结构后,必须定义一个初始化函数,在这里定义了一个名为GT2440_MCP2515_init()的函数,主要完成的工作有:
(1)软件复位,进入配置模式,设置CAN总线波特率,清空接收和发送缓冲区,切换MCP2515到正常状态,声明CAN的数据格式等。
(2)注册设备。注册设备所使用的函数原型是:int register_chrdev(unsigned int major,const char*name,struct file_operations *fops)其中major是主设备号,name是设备名称,fops就是内核访问设备的接口。
(3)注册设备使用的中断。因为中断信号往往是通过特定的中断信号线传输的,任何一款芯片留给中断信号的接口都是有限的,所以内核会维护一个中断信号线注册表,模块要使用中断就得向它申请一个中断通道,当它使用完该通道之后要释放该通道。这里使用的就是函数request_irq(MCP2515_IRQ,s3c2440_isr_mcp2515,SA_INTERRUPT,DEVICE_NAME,s3c2440_isr_mcp2515)。
对驱动程序的编译添加一般有两种方式:静态编译进内核和模块方式。为了便于调试,本文选择模块方式,首先将驱动程序复制到/linux-2.6.38.6/drivers/char中,然后经过相关配置后,使用insmod工具将编译好的模块加载到内核中,然后编写CAN总线测试程序,经过交叉编译后将测试程序下载到GT2440开发板中,最后在SecureCRT终端运行测试程序,验证了方案的可行性。
本文介绍了在GT2440和linux平台下扩展CAN总线控制器的具体方法,同时详细给出了开发CAN总线驱动程序的过程。随着嵌入式系统的发展,CAN通信设备与嵌入式系统的实际应用结合会越来越广泛。
[1]Microchip.带有SPI接口的独立CAN控制器[M].Microchip,2005.
[2]饶运涛.现场总线CAN原理与应用技术[M].北京:北京航空航天大学出版社,2007.
[3]宋宝华.linux设备驱动开发详解[M].北京:人民邮电出版社,2008.
[4]佟鸣宇,彭开香.基于ARM芯片的CAN总线接口设计与实现[J].计算机工程与设计,2009,30(7):1574-1576.