基于Can总线的嵌入式网络控制节点的设计与实现
明的是,上述伪码中在对临界区变量进行操作和判断时,即计算空闲区长度和判断饮_in_progress变量时,必须要在关闭设备中断条件下进行,操作完成后立即重新打开中断,下面描述的读函数中与临界区变量相关的操作也必须采用同样的机制。
读函数read的功能就是响应用户对CAN设备的读操作,如果接收缓冲区中已有了数据帧,则直接从缓冲区拷贝M字节的数据返回给用户,其中M为用户要求字节数与缓冲区已有数据字节数之间的较小值,更新读指针位置然后函数返回数值M,而如果当前缓冲区中无有效数据,则需要判断设备文件的读取模式,若为非阻塞模式,则直接返回,否则将读进程放入读操作等待队列睡眠,指定进程的最大睡眠时间并设置为睡眠可被信号中断模式,当任务被唤醒后,再对唤醒方式进行判断,若因睡眠时间结束而唤醒,则函数直接返回相应标识,否则说明缓冲区中已有数据,则执行上述的拷贝动作,并更新缓冲区的读指针位置,函数结束并返回实际读取字节数,具体实现略。
设备的iOCtl函数是用于设备控制的公共接口,可以根据设备的具体需求来实现相应的控制代码,在本文中共实现了三种功能,即清除读/写缓冲区、设置总线波特率、设置验收代码寄存器和验收屏蔽寄存器。
2.3 CAN设备的中断函数
如上所述,设备的读函数和写函数只是完成用户空间与设备的接收/发送缓冲区之间的数据帧传递,而真正的数据接收和发送工作,即芯片的寄存器与数据缓冲区之间的数据读取和写入,是由设备中断函数来完成。因此,实现中断函数既是驱动程序开发的核心,也是难点。下面是本例中使用的中断函数的伪代码:
ssize_tcan_isr_handle(......)
{
......
读Call芯片的中断状态寄存器,用来判断中断源类型;
if CAN接收中断
读芯片的RX帧信息寄存器,然后根据接收的数据帧类型,即标准帧或扩展帧,读取相应的ID寄存器和RX数据寄存器,并将各数值写入一个数据帧结构体中,再把读取的该数据帧拷贝到接收缓冲区中,缓冲区的写指针就是缓冲区的当前可写位置,拷贝完成后,更新写指针位置;
读控制器的状态寄存器,判断RXFIFO是否还有可用信息,若还有信息,则重复执行上述的数据读取操作,否则就判断读操作等待队列上是否有睡眠任务,有则唤醒它,中断函数结束;
else if CAN发送中断
判断设备的发送缓冲区是否已为空,若为空,则置tx_in_progress变量为0,并判断写操作等待队列上是否有睡眠进程,有则唤醒它,然后中断函数结束,
否则继续发送缓冲区中的数据帧,而缓冲区的读指针代表了缓冲区中当前需要发送的数据帧位置,发送完成后,更新读指针位置,并判断写操作等待队列上是否有睡眠进程,有则唤醒它,中断函数退出;
else即为其他中断
判断错误类型,并置位相应错误标识,然后分别判断写操作等待队列和读操作等待队列上是否有睡眠进程,有则唤醒它,中断函数退出;
}
当CAN控制器发生除接收中断和发送中断外的其它类型中断时,一般是根据具体的应用需求采取相应的处理措施。本例中采用了置位相应标识,由用户程序进行处理的方式。另外,驱动程序除实现上述的操作函数和中断函数,还应在模块初始化函数中完成设备注册、申请中断并注册中断函数及其他初始化工作;在模块清除函数中需要卸载设备并释放中断资源。
3 结束语
本文从软硬件两方面对基于ARM9芯片的CAN节点的具体设计过程进行了介绍,对硬件设计中的关键性问题和驱动模块实现结构都作了详细分析。目前,该CAN总线节点作为一个子系统已在某高速的网络化数据采集系统中得到应用,运行结果表明设备在CAN总线2.0B协议标准(兼容2.0A)下,数据发送、接收完全正常,满足了系统工作要求。本文给出的示例具有一定的普适性,对基于其他嵌入式设备上的CAN模块开发也有一定的参考价值。
Can总线网络控制节 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)