引言
在现代轿车的设计中,CAN网络应用广泛,将汽车内部众多的电子控制单元(ECU)组建,形成汽车电子控制网络,实现了在车载各ECU之间顺利进行信息交换。[13]
在构建汽车动力系统CAN网络的过程中,若使用星形总线结构,这必然使中心节点的CAN控制器负担加重,并且由于动力系统中节点个数较多,通信速率快,导致CAN网络负载加重,数据帧碰撞几率加大。在实际组网过程中,加入整车控制器(VMS)作为网关,将系统中的节点按传输速率及实时性要求分为CAN_A网及CAN_B网。
本文用Infineon公司的16位单片机XC164CS作为整车控制器的主MCU。它内部集成有片上TwinCAN模块,支持CAN2.0B 协议;同时拥有2个片上CAN控制器、2个同步串口、2个异步串口、ADC、CAPCOM1、CAPCOM2和CAPCOM6,这些功能模块应用于汽车控制器系统设计中,大大增强了系统的抗干扰性和工作的可靠性。在软件上采用TTCAN协议改进CAN的会话层,使总线上的数据传输更加有序、高效。在移植好的μC/OSII系统平台上编写CAN通信程序,可以很容易实现多任务调度,总线通信的实时性也更容易得到保证。
1 TwinCAN模块基本特性
1.1 TwinCAN简介
TwinCAN模块包括2个全CAN功能节点,这两个CAN节点可独立工作或者通过网关功能交换数据帧和远程帧。两个CAN节点共享TwinCAN模块的资源,能优化CAN总线通信处理,并使CPU负荷最小。全CAN功能还可与FIFO结构灵活组合,以满足复杂嵌入式系统的实时要求。
在XC164CS中有2 KB的RAM空间用于TwinCAN寄存器,这一地址区映射到SEG32中的0000H~07FFH,所有寄存器均为16位,内存地址分布如图1所示。CAN控制器由节点控制寄存器和报文对象组成。其中,节点控制寄存器包括控制/状态寄存器、中断寄存器、位定时寄存器、错误计数寄存器和中断屏蔽寄存器等。
1.2 报文对象
报文对象是CPU和CAN控制器之间通信的基本载体,主要用于发送和接收数据的存储器,TwinCAN模块中共有32个报文对象,图1中给出了报文对象的寄存器分布,每个报文对象的地址结构都基本相同。根据应用需要,这32个报文对象可独立地分配给两个CAN节点之一。各寄存器的功能可参阅XC164CS的用户手册。[45]
图1 TwinCAN模块地址映射
1.3 CAN报文对象缓冲器(FIFO)
当CPU负荷很重时,在某一报文对象被下一个由TwinCAN节点控制器提供的输入数据流覆盖之前,CPU可能很难处理该输入的数据帧。在实际应用中,有必要保证一个最低数据帧产生速率来满足外部实时要求,通常采用报文缓冲区就可以避免输入报文的丢失,同时将输出报文的建立时间减到最短。在TwinCAN模块中可以将某个报文对象配置成“基本对象”,再使用连续的“从属报文对象”作为单独的缓冲存储。组成缓冲区的基本和从属报文对象的数目必须是2的整数次幂,同时该缓冲区地址必须是这个缓冲区长度的整数倍,如表1所列。
表1 提供FIFO基本功能的报文对象
“基本对象”的定义是设置位域MMC为010B(控制寄存器MSGFGCRn),所要求的缓冲区大小是由位域FSIZE选择一个适当的值所决定;“从属报文对象”的定义是设置位域MMC为011B。在所有FIFO元素中,位域FSIZE必须相等,并且必须编程为同样的传输方向,设置为同样的标识符长度,且与同样的CAN节点关联。
在报文缓冲区和CAN总线之间的数据交换是受相关CAN控制器的管理。每个缓冲区按FIFO算法存储报文,CAN控制器发送或接收报文,它们以一个环形顺序进行。报文对象的寻址算法如下(CANPTR是被寻址的报文对象):
CANPTRn(new):=CANPTRn(old) &~FSIZEn | (CANPTRn(old)+1)&FSIZEn
2 TTCAN的工作原理
传统CAN总线的仲裁机制会导致传输延迟甚至信息丢失;各CAN节点之间时钟不同步,会导致网络无序、不确定。TTCAN是一种基于时间触发方式的CAN协议,在CAN 总线系统中实现TTCAN,首先需要解决的就是系统中多个节点的同步问题。TTCAN 需要同步总线中所有节点的通信调度,并且提供全局的系统时间。当网络中各个节点达到严格同步时,任何节点中信号的传输都在一个指定的时间窗口内进行发送,提高了总线的利用率。[6]
在TTCAN 中,存在一个时间意义上的主节点,被调度的节点都以计数器的形式保存着全局时间的副本;每隔一个网络时间单位,其计数器加1。为了在节点间建立和保持一定精度要求的时间同步,总线中时间主节点应该以一定的周期发送同步信号,建立同步基准。TTCAN的实现方式是其底层仍采用CAN 协议自身的仲裁机制,而在会话层中定义了调度时刻表,又称为“矩阵周期”。矩阵周期由多个基本周期组成,其机制与时间多路复用相类似,即调度时刻表由固定顺序的时间窗口组成,在TTCAN 中每个基本周期从出现同步信号开始,到出现下一个同步信号结束。
矩阵周期定义了整个系统的通信调度结构,它是包含所有通信信息的最小单元。TTCAN将消息分为事件型和周期型。如图2所示,事件型消息能在任一“仲裁窗”内发送,有可能参与仲裁;周期型消息则被分配了发送时刻,独享时长确定的“独占时间窗”,绝不会发生总线仲裁,准时而安全;“自由窗”内无消息发送,控制总线负载和升级备用。实质上,TTCAN系统软件的设计流程就是制订消息矩阵,将每一个具体的消息安排在矩阵周期中某一固定的时刻发送。
图2 TTCAN矩阵周期
3 CAN总线通信的硬件设计
XC164CS的2个全CAN功能节点A和B的硬件电路非常相似,因此本文只给出节点A的电路原理图,如图3所示。
图3CAN节点电路原理图
图3中,TLE6250是Infineon公司开发的CAN总线收发器,能应用于汽车和工业应用中高速、强电磁干扰环境下的数据传送,将来自CAN控制器的数据转换为CAN总线所需要的差动电平。TLE6250能接收来自5 V或3.3 V微控制器的数据(通过5脚选择),适用于12 V和24 V电源供电场合,可工作在正常工作模式、等待工作模式(可降低静态电流)和只接收工作模式(支持总线诊断功能)。为了增强CAN总线节点的抗干扰能力,XC164CS的CAN模块并不是直接与TLE6250的TXD和RXD相连,而是通过高速光耦6N137后与TLE6250相连,这样就很好地实现了总线上各节点之间的电气隔离。另外,光耦部分电路中所采用的两个电源Vcc和Vdd使用一个DC—DC转换器DCP010505P进行完全隔离,提高了节点的稳定性和安全性。
4软件设计
软件设计部分主要是在嵌入式操作系统μC/OS下编写CAN通信应用程序。用Infineon公司的DAVE软件对各模块进行初始化设置,生成模块驱动的C代码,结合实时操作系统μC/OS的软件平台,开发通信模块底层驱动软件以及多任务应用程序。
4.1 TwinCAN模块初始化
初始化设置包括两部分: 一是对CAN节点A和B的设置;二是对报文对象的初始化。
每一个CAN节点可以通过相关的节点控制寄存器的编程来单独设置,通过编程控制寄存器ACR/BCR、位定时寄存器ABTR/BBTR以及全局中断节点指针寄存器AGINP/BGINP,可选择CAN节点的工作模式,定义总线速率,允许或禁止不同类型的中断等。
对报文对象的初始化包括:设置报文关联CAN节点、报文标识符、屏蔽码及报文数据,设置网关及FIFO功能等。根据本系统的特点,将32个报文分为4组,每8个报文一组,均设置为FIFO功能,即有4个8级FIFO缓冲器。将这4组报文设置为两组接收、两组发送,再平分给两个CAN节点,每个报文对象的具体配置如表2所列。
4.2 驱动程序编写
利用DAVE软件,可方便地在图形用户界面上直接对所需的外设模块及寄存器进行功能配置,同时根据需要选择一些已经功能化的函数。完成相关配置并生成C代码以后,再对DAVE软件自动生成功能化的函数进行简单的修改,即可得到系统所需的驱动程序代码。[7]
各驱动函数及其功能描述如下:
ubyte CAN_Rep(ubyte ch)//复位CAN控制器函数
ubyte CAN_Enable(ubyte ch)//使能CAN控制器函数
ubyte CAN_SET_BANDRATE(ubyte ch,uword BTR)
//设置CAN控制器的比特率
ubyte CAN_Re_Err(ubyte ch)//错误计数器清零
ubyte CAN_Mode(ubyte ch,ubyte mode)//选择工作模式
void CAN_vTransmit(ubyte ubObjNr)//发送报文
void CAN_vConfigMsgObj(ubyte ubObjNr, TCAN_SWObj
*pstObj)//报文对象重配置
void CAN_vLoadData(ubyte ubObjNr, ubyte *pubData)
//装载数据
ubyte CAN_ubset(ubyte ubObjNr,ulong AR,ulong AMR)
//装载标识符及屏蔽码
ubyte CAN_ubmode(ubyte ubObjNr,ubyte mode)
//选择报文对象工作模式
ubyte CAN_ubWriteFIFO(ubyte ubObjNr, TCAN_SWObj
*pstObj) //写入FIFO
ubyte CAN_ubReadFIFO(ubyte ubObjNr, TCAN_SWObj
*pstObj) //读FIFO
ubyte CAN_ubFlushReadFIFO(ubyte ubObjNr)//清空FIFO
4.3 应用程序编写
首先对TTCAN协议进行一定的简单化处理: 在一个矩阵周期内只包含一个基本周期,即矩阵周期等于基本周期。这在矩阵周期比较短的情况下基本不会发生时钟漂移以及各控制器时钟不同步的情况。另外,各节点所享有的独占时间窗、仲裁窗和自由窗在时间上是连续的。这样控制器在时间安排上有了很大的自由度,也避免了因发送CAN报文带来的频繁的任务调度。
基于以上分析,在系统初始化后,建立了以下5个任务:void CAN_SendTimeStand, void CANA_SendMessage, void CANA_ReceiveMessage,void CANB_SendMessage和void CANB_ReceiveMessage。各任务都具有自己的堆栈空间,可以被其他任务或中断服务子程序删除或挂起。各任务之间通过信号量、邮箱、消息队列3种事件方式进行通信。CAN总线采用中断方式接收信息。由于参考时间消息对于TTCAN协议能否正常工作具有非常重要的意义,因此赋予CAN_SendTimeStand任务优先级5。图4为各任务在μC/OS中运行的主程序流程。
表2 报文对象FIFO配置
图4 主程序流程
在主程序中:
① 对XC164CS以及μC/OS进行初始化,调用OSInit()函数;
② 创建5个任务以及信号量、邮箱及消息队列,系统时钟节拍设置为250 Hz,每个任务分配128个OS_STK堆栈空间;
③ 调用OSStart()函数,系统开始运行优先级最高的任务CAN_SendTimeStand;
④ 运行完毕后程序延时5个时钟节拍,CAN发送任务进入就绪态,当发送完所有的数据帧后任务挂起,并等待CAN_SendTimeStand将其激活;
⑤ CAN总线采用中断方式接收信息,每5个时钟节拍是一循环,完成TTCAN矩阵周期所有数据的传送。
各个任务之间的调度如图5所示。
图5 CAN通信程序信息流
图5中,序号的含义如下:
① CAN_SendTimeStand任务向A、B两节点同时发送参考时间消息,发送完毕后发出信号量,TTCAN的新的矩阵周期开始;
② CANA/B_SendMessage获得信号量,开始运行;
③ CANA/B_SendMessage任务从消息队列中取出待发送的数据,更新其节点对应的发送FIFO缓冲器,并通过CAN总线依次将数据发送出去;
④ 控制器接收到来自CAN总线中的数据,通过CAN接收中断发出信号量;
⑤ CANA/B_ReceiveMessage任务获得信号量,从接收FIFO缓冲器中取出数据,经过数据处理之后通过μC/OS的邮箱机制发送给其他任务。
由于TTCAN协议严格规定了各消息在矩阵周期中传输的时间窗,所以CAN控制器不应在发送数据帧时使能其自动重发功能(可通过CAN_ubmode函数选择单次发送数据模式),而应由软件控制,将发送失败的帧在仲裁窗中重新发送。
5 结论
本文选用Infineon公司16位单片机XC164CS,利用其内部的TwinCAN模块,设计了适用于车载整车控制器的CAN通信网络,开发了相应的硬件接口电路;利用有序的TTCAN协议,在基于实时操作系统μC/OS的软件平台下,编写了通信模块底层驱动软件以及多任务应用程序,实现了车载动力系统控制和信息交换,提高了系统的抗干扰性和可靠性。