原创 基于ARM920T的两种CAN总线扩展方式 二

2013-7-4 09:30 1616 18 18 分类: MCU/ 嵌入式
  3.2.1 IO接口连接

    微处理器的通用IO口可以提供一个简便的方法来控制SJA100T。EP9315的GPIO信号提供了很大的灵活度来满足SJA1000T 时间上的要求。将SJA1000T数据地址复用总线全部与EP9315的通用IO接口连接。其它信号线WR、RD、ALE……也与IO接口连接。具体连接 方式参考图2。

    22.jpg

    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有中断功能。

    33.jpg

    图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(),重新使能中断。中断处理过程如图所示:

    44.jpg

    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驱动程序;最后对两种扩 展方式做了简单的比较。该现场总线控制系统在国家十一五某国防项目中得到了很好的应用。同时也为大中型国有企业自动化生产线的建设和改造,电力系统自动化 的实现提供很好的借鉴。

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
18
关闭 站长推荐上一条 /3 下一条