1、引言
随着工业控制系统逐步的自动化,现代化,现场总线控制系统得到越来越多的重视和应用,CAN总线是目前开发简单,性能价格比高的一种现场总线 。相对其他现场总线而言,CAN通信控制器的生产厂家最多、品种最全、应用也最为广泛。基于现场总线控制系统智能化、复杂度的提高,作为现场总线的核心部件微处理器,传统的51芯片,甚至ARM7已经逐渐不能满足需要,ARM9成为合适的选择。但许多ARM9并没有集成CAN接口,扩展CAN接口成为当务之急。且ARM9将数据地址总线分开,而CAN控制器为数据地址总线复用,使得CAN的扩展不能一味照搬51处理器的方式。在CAN模块驱动开发上,现有资料往往只针对Linux系统上的驱动开发 进行介绍,而现场总线控制系统对实时性的要求使得Linux系统要让位于更多的实时操作系统。
本文介绍了一种基于ARM920T现场总线的控制系统,详细说明了其上扩展CAN总线的两种方式,并给出具体的CAN模块在实时操作系统eCos 上驱动程序开发的步骤,最后对两种扩展进行了简要的比较。
2、现场总线控制系统简介
该现场总线控制系统采用EP9315为核心处理器。EP9315是Cirrus Logic公司开发的一款基于ARM920T的工业级处理器。该现场总线控制系统除了外扩的CAN总线接口、还外扩64Mb SDRAM和32MB FLASH、并带有PCMCIA 接口、E PROM接口、512kb SRAM、IDE接口、实时时钟、视频显示、彩色VGA TFT LCD触摸屏、支持模拟VGA连接、视频解码支持压缩视频输出和S-VIDEO输出、PS/2键盘,三个USB接口、三个串行接口、音频接口、1/10/100Mbps以太网接口、红外线接收口;实现了控制系统的数字化、智能化;可实现多种功能,使系统的控制功能本地化,提高了系统的可靠性、实时性;简化了系统的结构。多接口的系统结构使系统的扩展,变更,拆装更加灵活便利。
3、硬件系统扩展
3.1 CAN总线模块结构
本文使用SJA1000T作为CAN控制器扩展CAN模块 。SJA1000T是使用于汽车和一般工业环境的独立CAN总线控制器,具有完成CAN高性能通信协议所要求的全部必要特性;具有简单总线连接的SJA1000T可完成物理层和数据链路层的所有功能。支持CAN2.0协议。
CAN总线收发器TJA1040T是CAN控制器和物理总线之间的接口芯片,增强了总线的驱动能力,从而增加CAN总线的通信距离并使得一条总线上可以挂更多的节点。
为增强CAN总线节点的抗干扰能力 ,SJA1000T的TXO和RXO并不直接与TJA1040的TXD和RXD相连,而是通过两片光耦隔离芯片6N137与TJA1040T相连。很好地实现了收发器与控制器之间的电气隔离,保护智能节点核心电路安全工作;并实现了总线上各CAN节点间的电气隔离。需要强调的是:为实现这种电气隔离,光耦器件两侧的直流电源必须是两个无直接电气联系、相互隔离的直流电源。因而采用两路DC-DC隔离电源实现。为进一步加强安全性和抗干扰能力,可在总线收发器TJA1040T与CAN总线间串接限流电阻,避免TJA1040T受过流冲击。同时,在CANH和CANL,与地之间并联了滤波电容,可以起到滤除总线上的高频干扰,并具备一定的防电磁辐射能力。此外,通信信号在线路上传输时,信号传输到导线的端点时会发生反射,反射信号会干扰正常信号的传输。为消除这种影响,可在CAN总线两端并接匹配电阻,起到匹配总线阻抗和消除反射的双重作用。若忽略这些措施,会使数据通信的抗干扰性和可靠性大大降低,甚至无法通信。
3.2 CAN模块与ARM9的两种连接方式
SJA1000T数据地址总线复用,而整个ARM9系列包括ARM920T数据和地址总线分开。这就使得它与ARM9系列的连接不能像传统的用于51单片机系列方式扩展连接,本文给出两种扩展方式 :全部IO口连接方式和最少IO口的数据信号线连接方式。
3.2.1 IO接口连接
微处理器的通用IO口可以提供一个简便的方法来控制SJA100T。EP9315的GPIO信号提供了很大的灵活度来满足SJA1000T时间上的要求。将SJA1000T数据地址复用总线全部与EP9315的通用IO接口连接。其它信号线WR、RD、ALE……也与IO接口连接。具体连接方式参考图2。
3.2.2 数据信号线连接
除了全部由IO端口来控制CAN模块,还可利用ARM9的数据线和信号线来实现CAN模块的扩展。连接电路如图3所示,凡SJA1000T以外的信号均为EP9315芯片上的信号管脚,SJA1000T数据地址复用总线与EP9315数据线相连,GPIOx、GPIOy、GPIOz可以是EP9315任意GPIO引脚,但选择同一个通道的GPIO口将使编程更容易。注意SJA100T的INT可以连接CPU的INT也可以连接到带有中断的通用IO上。在EP9315中,GPIO的通道A,B,F有中断功能。
图2和图3是示意图,具体的由于EP9315信号高电平为3.3V,而SJA1000T高电平为5V,故需要通过74LVC245这类电平匹配芯片进行电平匹配后再连接。
4、驱动开发
由于现场总线控制系统在许多场合具有实时性的要求,本现场总线控制系统采用实时性高的eCos作为操作系统,CAN驱动程序也在eCos操作系统 上进行扩展。
对eCos系统的设备驱动程序的设计主要围绕着DEVTAB_ENTRY和DEVIO_TAB进行,添加新设备的工作就是对这两个表项的各个域进行实现,并且编写与硬件相关的底层函数。通过对驱动程序结构层次的剖析,CAN总线驱动的开发分为四步:
第一步:向内核注册新设备;
第二步:开发驱动程序基本IO函数;
第三步:实现中断处理函数;
第四步:绑定设备中断并进行验证。
具体实现过程如下:
4.1 向内核注册新设备
在向内核注册新设备时,原有的驱动程序中和硬件无关的部分仍然可以使用,例如设备I/O函数表,硬件相关的部分需要自行设计,包括设备描述符、设备名、设备初始化程序init、查找程序lookup和拓展CAN总线的数据结构。
拓展CAN总线的数据结构Can_bus时一组用于描述对设备进行的全部操作的数据结构。通过宏Can_bus产生can总线的数据结构,宏Can_bus的原型为:
Can_bus(1,funs,modereg,intrenreg,bustime,outpctr,clkdiv,acptcode,acptmask,flag)
参数说明如下:
l-该数据结构的语言标识符
funs接口函数组,即硬件接口函数。
flags驱动程序初始表示值。
modereg工作模式初始值
intrenreg中断允许初始值
bustime总线时钟1,和总线时钟2初始值
outpctr输出控制
clkdiv分时
acptcode验收代码
acptmask验收屏蔽
在产生CAN总线的设备表入口时首先要创建can总线的数据对象Can_bus,并且初始化以上所有参数。拓展CAN总线的Can_bus数据对象标识符为EP9315_can_bus。
拓展CAN总线的设备表入口对象实现如下:
DEVTAB_ENTRY(EP9315_can_io0,
CYGDAT_IO_CAN_EP9315_CAN0_NAME,
0,
&cyg_io_can_devio,
EP9315_can_init, //拓展CAN的初始化函数
EP9315_can_lookup, //拓展CAN的查找函数
&EP9315_can_bus //CAN数据结构Can_bus
);
4.2 开发驱动程序基本IO函数
这部分函数指的是驱动程序接口函数中与硬件相关的部分,也就是Can_bus数据结构中的funs接口函数表。funs函数表通过以下宏进行定义:
CAN_FUNS(l,putc,getc,set_config,start_xmit,stop_xmit)
参数说明如下:
l是该funs函数表的C语言标实符。
putc函数:bool (*putc)(can_bus *priv,unsigned char c)该函数发送一个字符到串口。如果发送成功,则返回true,否则返回false。
getc函数:unsigned char (*getc)(can_bus *priv)该函数从设备接口读取一个字符,它只用于非中断方式,通过查询设备是否处于准备(ready)状态来等待一个字符。
set_config函数:bool (*set_config)(can_bus *priv,cyg_can_info_t *config)该函数用于对指定的端口配置。如果对硬件配置成功,则返回true;如果端口不支持给定的配置参数,则返回false。
start_xmit函数:void (*start_xmit)can_bus *priv)在中断方式下,该函数使能发送端,允许发送中断的产生。
stop_xmit函数:void (*stop_xmit)(can_bus *priv)在中断方式下,当数据发送结束后,该函数进制发送端,进制发送中断产生。
start_recv函数:void (*stop_xmit)(can_bus *priv)
stop_recv函数:void (*stop_xmit)(can_bus *priv)
4.3 发送中断处理函数
CAN总线在中断方式下的负责对中断进行处理函数是中断服务程序ISR和中断滞后服务程序DSR。对中断的处理主要有三种模式,第一种模式是在中断服务程序ISR内完成所有设备处理工作,第二种是在中断滞后服务程序DSR内实现,第三中是将对设备的处理推迟到中断线程内进行。在驱动程序的设计中采用的是第二种模式。
在这种模式中,中断处理程序ISR只是简单的通过对设备进行编程或者直接调用cyg_drv_interrupt_mask()函数防止新中断的产生,然后将调用DSR作进一步的处理。DSR完成大部分的硬件处理工作,并有可能对某个条件变量产生一个信号来唤醒新的中断。最后,DSR调用cyg_drv_interrupt_unmask(),重新使能中断。中断处理过程如图所示:
4.4 绑定设备中断
设备驱动程序的初始化函数在系统初始化过程或者设备初始使用时被调用,初始化函数不仅要设置设备的参数,还要为设备分配相应的数据结构:例如输入输出缓冲区等,最后还将设备中断进行绑定。
每一个设备在初始化时会产生一个对应的中断对象,所有的中断对象存储在系统的中断向量链表中。当某个中断发生时,系统根据中断码到中断向量链表中寻找相应的中断对象,再跳转到中断对象记录的中断处理程序的位置执行。
宏cyg_drv_interrupt_create(vector,priority,data,isr,dsr,handle,intr)用于产生设备的中断对象。其中,vector是中断向量,priority中断优先级,data是数据指针,isr是中断处理程序ISR的地址,dsr是中断滞后处理程序DSR的地址,handle是返回句柄,intr是中断对象存放的位置。
宏cyg_drv_interrupt_attach(interrupt)用于将中断向量加入到中断向量链表。参数interrupt是将要连接的中断的句柄。
设备中断绑定后,当设备产生中断时系统会找到相应的中断向量,然后把控制权交给中断处理程序,进行中断的处理。
5、两种扩展方式比较
对于两种不同的CAN与ARM9连接方式,IO口连接直观简单;而利用数据信号线连接能节省IO口,给CPU更多开发空间。两者在驱动程序上差异不大,主要体现在底层数据读写时序实现上。前者简单易于编写和理解,后者只是在对时序的理解上略有难度,并不会使代码更加冗长。
6、结束语
本文通过在现场总线控制系统上扩展CAN总线模块,详细讲解了如何在ARM9上扩展CAN总线模块,给出了全IO口扩展和利用数据信号线扩展两种方式;并详细说明如何在高实时性操作系统eCos上开发CAN驱动程序;最后对两种扩展方式做了简单的比较。该现场总线控制系统在国家十一五某国防项目中得到了很好的应用。同时也为大中型国有企业自动化生产线的建设和改造,电力系统自动化的实现提供很好的借鉴。
参考文献
[1] 史久根等. CAN现场总线系统设计技术[M]. 北京:国防工业出版社,2004.
[2] 邬宽明. CAN总线原理和应用系统设计[M]. 北京:北京航空航天大学出版社,1995.
[3] 王京起等. 嵌入是可配置实时操作系统eCos技术及实现机制[M] . 北京:电子工业出版社,2005.
[4] 张绍忠,王辉. 基于SJA1000的CAN总线智能节点实现[J].电子技术应用,2006(8):22-25.
[5] 王松月,杨福兴. 基于ARM920T嵌人式通信控制系统设备驱动开发[J].电力自动化设备, 2006.26(6):75-78.WANG Song-yue, YANG Fu-xing,Driver development for embedded communication control system based on ARM920T[J]. Electric power Automation Equipment,2006,26(6):75-78.
[6] Freund L, Dupont D, Israel M, Rousseau F. Overview of the ECOS project[J]. Rapid System Prototyping, 1997’Shortening the Path from Specification to Prototype’. Proceedings, 8th IEEE International Workshop on 24-26, 1997.6:39-43.
[7] Anthony J. Massa. Embedded Software Development with eCos[J]. PRENTICE HALL, Publishing as Prentice Hall Professional Technical Reference, 2003, 7-10, 315-322.
[8] How to Connect NAND Flash Memory to an EP93xx[J]. http://www.cirrus.com. 2005.2.<