《电子技术应用》
您所在的位置:首页 > 通信与网络 > 业界动态 > 基于缓冲管理的MCP2515驱动实现

基于缓冲管理的MCP2515驱动实现

《电子技术应用》
2008-03-21
作者:刘光伦,廖建明

  摘 要: 针MCP2515芯片的特点,提出了一种新的MCP2515驱动实现方法。把MCP2515的SPI口同MCU的SPI口相连,在EVC下用SPI接口的方式实现MCP2515的驱动。在驱动中,再加上了缓冲管理机制和双注册的机制,避免CAN总线上的干扰数据。
  关键词: 缓冲 双注册 MCP2515 CAN总线 SPI


  在WINCE的驱动编写中,一般都采用标准的编写方式,即分层式结构[1]。分层式结构驱动程序依赖于一段可在平台间再使用的代码,以简化和缩短开发时间。这段由微软提供的代码称为模块设备驱动程序MDD,用来实现驱动程序的核心功能。MDD并不直接存取硬件,而是依靠另一段与硬件有关的代码存取硬件,这段代码被称为平台相关驱动程序PDD。当将一个平台的分层驱动程序用于另一个平台时,只要重写PDD即可,而不必重写整个驱动程序。MDD和PDD之间有一个设备驱动程序服务提供商的接口DDSPI,该接口定义了一些PDD功能,这些功能在执行期间内被MDD调用。这种方法相对来说要简单一些,因为有模版可用,但在调试驱动的时很不方便。因为分层结构的驱动和WINCE的内核是密切相关的,在调试驱动程序时,必须先把内核编译好,然后下载内核到目标平台上,才能够调试,因而效率很低。本文采用另一种脱离内核的方式在WINCE中实现MCP2515的驱动程序,即在EVC的平台下,通过SPI接口来做驱动MCP2515的工作。这样,编写的驱动直接编译成一个动态链接库" title="动态链接库">动态链接库DLL,把这个动态链接库拷贝到目标平台上,就可以使用。而且,通过这种方式,实现了更加灵活的功能。
1 MCP2515芯片介绍
  CAN(Controller Area Network)总线[2],即控制器局域网总线,是一种有效支持分布式控制或实时控制的串行通信网络。由于其高性能、高可靠性及独特的设计和适宜的价格而广泛应用于工业现场控制、智能楼宇、医疗器械、交通工具以及传感器等领域。CAN是一种基于广播方式的协议,主从式网络结构,也是一种串行数据通信协议,一种多主总线,通信介质可采用双绞线、同轴电缆或光纤。
  Microchip公司推出的CAN总线控制器芯片MCP2515符合CAN2.B技术规范并带有符合工业标准的SPI串行接口,是目前市场上体积最小、最易于使用也是最节约成本的独立CAN协议控制器芯片[3][4]。MCP2515具备最高40MHz时钟输入速度以及一个10MHz高速SPI接口,还可根据前两个数据字节和11位标识符对报文进行滤波。
  MCP2515能够发送和接收标准数据帧" title="数据帧">数据帧以及扩展数据帧,并具有接收过滤和信息管理的功能。MCP2515通过其SI引脚同MCU进行数据传输,最高数据传输速率可达1Mbps。MCU可以通过MCP2515与CAN总线上的其他MCU进行通信。MCP2515内含三个14 字节的发送缓冲器,二个14字节的接收缓冲器,并且具有灵活的中断能力、帧屏蔽和过滤、帧优先级设定等特性。
  MCP2515的主要功能参数:(1)支持CAN协议2.0A/2.0B;(2)最大" title="最大">最大可编程波特率为1Mbps;(3)有标准帧和扩展帧两种数据帧可供选择,每个帧中的数据段长可为0~8字节;(4)支持远程帧;(5)内含3个发送缓冲器和2个接收缓冲器,并且其优先级可编程设定;(6)内含6个29字节的接收过滤器和2个29字节的接收过滤屏蔽器;(7)具有(loop-back)自环检测模式;(8)标准帧数据段的前两个字节的单独过滤功能。


  图1为MCP2515的内部结构原理图,其中CAN模块包括CAN协议机和发送、接收缓冲器以及他们的屏蔽器、过滤器。CAN协议机主要负责与CAN总线的接口,SPI接口逻辑负责实现与MCU的接口,而缓冲器、过滤器组和控制逻辑以及与之相关的位定时发生器、控制和中断寄存器则负责实现各种工作模式的设定和操作控制。MCP2515芯片在CAN总线上的数据接收是通过2个接收缓冲器、2个接收屏蔽器、6个接收过滤器的组合来实现的。CAN总线上只有同时满足至少任意一个接收屏蔽器和一个接收过滤器的条件的帧,才可以进入接收缓冲器。MCU可以通过SPI接口来读取MCP2515接收缓冲器里的数据。MCP2515对CAN总线的数据发送则没有限制,只要用MCU通过SPI接口将待发送的数据写入MCP2515的发送缓冲器,然后再调用RTS(发送请求)命令即可将数据发送到CAN总线上。MCU通过使用标准SPI读写命令对MCP2515寄存器进行读写操作。
  MCP2515具有灵活的中断管理功能。它有8个中断源,包括发送、接收中断、各种错误中断以及总线唤醒中断等。MCU可以通过对MCP2515的中断允许控制寄存器CANINTE的设置来设定和屏蔽各种中断的发生条件,并可以通过读取MCP2515的中断标志位寄存器CANINTE或者读取CANSTAT寄存器中的ICOD部分来判断当前中断的中断源。
2 缓冲管理的驱动实现
2.1 驱动框架和流程

  按照WINCE的标准的分层结构来实现MCP2515的驱动,由于分层结构的WINCE驱动程序和操作系统内核是紧密结合在一起的,调试驱动时效率很低,而且这种方式实现的驱动,功能也不够灵活,所以本文不再采用这种方式,而是直接在EVC下用SPI接口的方式来操作MCP2515芯片。硬件采用三星的ARM内核的S3C2440A,该CPU带有2通道SPI口,可以直接和MCP2515带的SPI相连。S3C2440A通过SPI口就可以操作MCP2515芯片,实现CAN协议的数据收发。
  在CAN总线中,各种在CAN总线上传输的数据帧都被分配一个惟一的标识符,每个节点根据这些标识符来确定是否接收这些帧。当然还必须与过滤器及屏蔽器配合,共同决定是否接收数据" title="接收数据">接收数据。
  本文提到的CAN总线分成父设备和子设备,子设备会主动把自己的数据上传给父设备,父设备收到数据后,对这些数据进行进一步的处理,例如,在屏幕上以图表的形式显示出来等。图2显示了CAN总线的网络结构。

 

 


  CAN父设备就是一个带有MCP2515芯片的ARM嵌入式系统。CAN子设备也可以是一个带MCP2515的嵌入式系统,也可以是其他一些CAN设备。本文中主要介绍MCP2515在CAN父设备上" title="设备上">设备上的驱动程序实现。图3是驱动程序框图。
  MCP2515主要提供了状态查询以及中断两种数据操作模式,本文中MCP2515主要采用状态查询模式进行CAN总线数据的接收和发送。在系统上电后,先对MCP2515芯片进行初始化的工作,主要是设置MCP2515芯片的相关寄存器的值,如设置波特率,屏蔽寄存器,过滤寄存器等。初始化工作完成后,开启一个线程负责收发数据。如果发送缓冲中有数据需要发送,则发送数据,否则,查询MCP2515的CANINTF寄存器的第0和1两位,如果有数据则接收数据,然后判断该帧ID是否在父设备上注册,如果已注册,则把数据放到接收缓冲区中,否则,就丢掉继续循环,直到这个线程终止。
2.2 接收缓冲
  在驱动中,为了保证接收的数据不会丢失,需要添加一个缓冲,用来缓存接收到的数据。在接收缓冲中,完全以帧的形式存放,方便后续的数据处理。在CAN总线中,主要有以下的几种帧:
  数据帧:数据帧携带数据从发送器至接收器。
  远程帧:总线单元发出远程帧,请求发送具有同一识别符的数据帧。
  错误帧:任何单元检测到总线错误就发出错误帧。
  过载帧:过载帧用以在先行的和后续的数据帧(或远程帧)之间提供附加的延时。
  当然,驱动程序并不缓存所有的帧,只缓存需要的数据帧和远程帧,以下是驱动中定义帧结构的数据成员:
  DWORD      dwID;
  BOOL      bRemoteFlag;
  BOOL      bExternFlag;
  BYTE      DLCLen;
  BYTE      Data[9];
  结构名称为CAN_RECV_FRAME,dwID为帧ID,bRemoteFlag是远程帧标志,bExternFlag 为扩展帧标志,DLCLen是数据长度,它可以是0~8中的任何数值,Data[9]是帧数据的缓冲区,最多使用其中8个字节。然后定义CList类型的成员变量m_RevList作为一个接收的队列:
  CListm_RevList;
  在对缓冲区初始化时,一次就分配了足够的数据空间,而不必在使用时再动态申请内存,这样保证了系统占用的内存资源的确定性。线程在存取缓冲区时必须要事先锁定,保证在一个时刻只有一个线程对缓冲区进行存取操作。为了提高对资源的利用率,驱动中把缓冲变成一个循环队列,再定义了一个RECV_FRAME_USE的结构来管理缓冲区,该结构的数据成员如下:
  POSITION     pHead;
  POSITION     pTail;
  Int        iLen;
  pHead是头指针,pTail是尾指针,iLen为队列使用长度。有了RECV_FRAME_USE这个结构后,缓冲区就成了一个帧的循环队列。在系统收到帧时,就把该帧放到队列的后面。如果数据缓冲区已满,则清空头一帧,实现先进先出。在没有加上过滤以前,收到的总线上的所有的数据帧都放在缓冲中。
2.3 发送缓冲
  发送缓冲区和接收缓冲区不同,接收缓冲区之所以这样设计,是因为在MCP2515收到数据后,要进行解帧,把帧ID、帧的类型、数据长度和数据这些信息分开,分别存放在帧结构的对应变量中,这样可方便后续的处理。但是在发送时必须先进行组帧,而且要让MCP2515把数据发送出去,必须把帧的数据(如帧ID、何种帧、数据的长度以及数据等)按MCP2515的要求,送到MCP2515相应寄存器中的对应位。所以,在组织发送数据时,必须把要发送的数据按照MCP2515的寄存器要求进行组织,这样在发送时,直接把组织好的数据逐字节送到对应的MCP2515的寄存器即可。MCP2515有三个14字节SRAM发送缓冲,并映射到存储器中。其中第一字节TXBNCTRL 是与报文缓冲器相关的控制寄存器。该寄存器中的信息决定了报文在何种条件下被发送,并在报文发送时指示其状态。用5个字节来装载标准和扩展标识符以及其他报文仲裁信息。最后8个字节用来装载等待发送的报文的8个可能的数据字节。所以,在发送缓冲区中,只保存5个字节的标准和扩展标识符以及其他报文仲裁信息,8个字节用来保存发送的数据。在驱动中,定义了一个名为MCP2515_SEND_BUFFER的发送缓冲区,以下是该缓冲区的数据成员。
  DWORD    dwWritePointer;
  DWORD    dwReadPointer;
  BYTE     Data[MAX_SEND_LEN]
  该缓冲区也是一个循环缓冲,dwWritePointer为发送缓冲的写指针,dwReadPointer为发送缓冲的读指针,Data就是存放帧数据的队列,MAX_SEND_LEN为队列的最大长度。该队列的数据格式是:长度+5个字节标示符+数据。因为数据的长度最大为8个字节,得出长度最大就是13个字节。所以,长度用BYTE型就可以表示了,这样pData存放的数据就很规整。在发送时,从pData中取走一帧后,直接把前5个字节标准和扩展标识符以及其他报文仲裁信息和后面数据字节送到MCP2515对应对寄存器即可,不用解帧和组帧过程,从而加快发送进程。
2.4 双注册机制
  MCP2515芯片具有两个验收屏蔽寄存器(分别对应不同的接收缓冲器)以及六个验收过滤寄存器,它们共同来决定报文是否应被载入接收缓冲器。 一旦报文集成缓冲器(MBA)接收到有效报文,报文中的标识符字段将与过滤寄存器中的值进行比较。如果两者匹配,该报文将被载入相应的接收缓冲器。滤波屏蔽寄存器用来确定滤波器对标识符中的哪些位进行校验,这样可以直接屏蔽一些不希望收到的数据。这一机制对于所有的有MCP2515芯片的设备都是有用的。在利用缓冲区来缓存收到的数据后,毕竟驱动程序中的缓冲区大小受限,有时并不需要把所有收到的数据放在缓冲中,所以对进入缓冲区的数据再加上一次过滤,即在父设备上注册的机制。只有在父设备上注册了ID的子设备,父设备才会把数据放到数据缓冲区中。在父设备的驱动中,有一个列表专门用来保存子设备注册的ID,每次父设备收到数据在放到缓冲区中以前,都会比较一下,在列表中有没有这个ID,如有就放到缓冲区中,如没有则丢掉。这样又可以屏蔽掉总线上的一些无关的数据,从而提高了效率。
  本文详细介绍了MCP2515在WINCE中的实现过程和主要技术,但是限于篇幅,没能给出详细的软件源程序。实践证明,该驱动在CAN总线实际的应用中效果明显,既提高了开发的效率,又实现了更灵活的功能。
参考文献
1 Boling D.Microsoft Windows CE程序设计.北京:北京大学出版社,1998
2 饶运涛.现场总线CAN原理与应用技术.北京:北京航空航天大学出版社,2003
3 Microchip公司.MCP2515,Stand-Alone CAN Controller With SPITM Interface.2003
4 Microchip公司.AN215,A Simple CAN Node Using the MCP2510 and PIC12C67X.2002

本站内容除特别声明的原创文章之外,转载内容只为传递更多信息,并不代表本网站赞同其观点。转载的所有的文章、图片、音/视频文件等资料的版权归版权所有权人所有。本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如涉及作品内容、版权和其它问题,请及时通过电子邮件或电话通知我们,以便迅速采取适当措施,避免给双方造成不必要的经济损失。联系电话:010-82306118;邮箱:aet@chinaaet.com。