Linux环境下实现ARM9的CAN总线通信

linux环境下实现arm9的can总线通信
1. 引言
can(controller area network)总线最早是由德国bosch公司提出,实现汽车环境中的微控制器通讯,在车载各电子控制装置ecu之间交换信息,形成汽车电子控制网络。由于其具有成本低,实时性好,容错性高,设计灵活等特点,目前已被广泛的应用于各种工业领域,被公认为是最有前途的现成总线之一。与此同时,随着arm(advanced risc machines)芯片及嵌入式linux操作系统的成熟与完善,使得can通信的开发更为便利,应用更为广泛。本文就将从硬件,软件两方面介绍一种在linux环境下实现基于ep9315的can总线通信方式。
2. 硬件介绍及其接口实现
本设计选用的是cirrus logic公司推出的ep9315处理器及philips公司推出的sja1000独立can控制器。下面先对两款芯片作简要介绍,再对can接口硬件电路设计作详细说明。
2.1 ep9315及sja1000芯片简介
ep9315是ep93xx系列微处理器的旗舰产品。内嵌先进的运行于200mhz(工业条件下推荐运行184mhz)的arm920t微处理器核,以及支持linux,windows ce等操作系统的存储器管理单元mmu,16kb指令高速缓存和16kb数据高速缓存可为现有的程序和数据提供零等待时间,或者以锁存的方式确保对关键指令和数据的无延迟存取。ep9315内部集成了maverickcrunch 数学协处理器和maverickkey 硬件可编程id,前者显著提高了arm920t的浮点,整形运算与信号处理能力,同时它还具有丰富的集成外设接口,包括1/10/100mbps以太网mac,3通道usb2.0全速主口,spi、i s和ac’97串行接口,pcmcia接口,raster/lcd接口,图像加速器,带12位a/d转换器的触摸屏接口,键盘接口,uart接口,丰富的gpio,支持4组32位sdram的无缝连接等。
sja1000是一款高性能的can控制器,支持basiccan和pelicanl两种工作模式,提供intel和motorola两种寻址方式,地址线和数据线分时复用,sja1000基于寄存器编址,可以通过读写寄存器来操作它。
2.2 硬件接口电路设计
ep9315带有16个增强型gpio,可以通过配置padr、paddr寄存器使得egpio2控制sj1000的ale址锁存信号,egpio3接收sja1000的中断信号,并且可以配置中断类型。由于sja1000的数据线与地址线分时复用, 当在送地址时,rd、wr、cs信号必须无效,送数据或读数据时,rd、wr、cs信号才有效,因此结合cpld(epm7032芯片)或是一些逻辑门来实现该逻辑,并片选两个bank来分别用于地址操作(ncs5_phybase 0x50000000)和数据操作(ncs3_phybase 0x30000000)。当读sja1000时,首先由ep9315通过cs选通sja1000,通过egpio2使得ale有效,锁存地址,并由cs5经cpld选通flash的bank5,将地址存入映射后的bank5区域,然后使得ale为0取消地址锁存,最后置低ep9315的rd信号,经74lv32后使得sja1000的读信号有效,完成读操作;写操作时,同理选通sja1000,使能ale,发送地址并将其锁存在bank5,然后取消ale,置低ep9315的wr信号,通过74lv32使能sja1000的wr信号,接着发送数据置映射后的bank3,将数据写入sja1000,完成写操作。
3. 软件分析及实现
本文采用linux系统,内核版本为2.4.21-rmk1,搭建arm-linux交叉编译环境同时利用动态模块加载法来进行驱动开发。模块化的优点在于能将内核映像尺寸保持在最小,并且具有最大的灵活性,便于检验新的内核代码而不需重新编译,引导内核。shell用户应用程序的开发主要采用了gdb远程调试技术,该调试环境由宿主机gdb和目标机调试stub共同构成,两者通过串口或tcp连接。驱动程序与应用程序的整体流程图如图2所示。
图2 驱动程序与应用程序的整体流程
3.1 linux下can驱动的实现
can设备属于字符型设备,是以字节为单位逐个进行i/o操作的设备,在对它发出读写请求时,实际的硬件i/o紧接着就发生了。字符型设备的缓存是可有可无的,而且也不支持随机访问。应用程序可以通过标准系统调用像访问字节流(类似文件)一样来打开,读,写,关闭字符型设备。
驱动程序主要由一下4个关键环节组成:
⑴模块的初始化 module_init(mysja1000_init)
模块的初始化函数负责注册模块所提供的任何设施。module_init的使用是强制性的,这个宏会在模块的目标代码中增加一个特殊的段,用于说明内核初始化函数所在的位置。没有这个定义,初始化函数永远不会调用。当模块正常初始化时,在初始化函数中完成了对can设备以及设备中断的注册,对sja1000芯片中相关寄存器的配置,对ep9315中的egpio口的初始化设置,并且利用函数void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags) 将io地址空间映射到内核的虚拟地址空间上去,这样就可以像读写ram那样读写io内存资源了。⑵服务于i/o请求的子程序
这部分程序又被称为是驱动程序的上半部分。调用这部分程序是由于系统调用的结果。当该部分程序执行时,系统仍认为是与进行调用的进程属于同一个进程,只是由用户态变成了核心态。由于此部分程序是驱动程序与应用程序的接口,所以必须通过linux下的一个关键的数据结构file_operations来实现该文件操作接口。file_operations结构中的成员几乎全是函数指针,实质上是一个函数跳转表。例如can_open入口点用来打开can设备准备进行i/o操作;can_read入口点用来实现接收can数据帧;can_write入口点用来实现发送can数据帧;can_ioctl入口点提供了一种执行can设备特定操作的方法,通过ioctl来实现对sja1000寄存器的读写操作,使用户根据需要方便的配置sja1000状态等等。
⑶中断服务子程序
这部分程序又被称为是驱动程序的下半部分。linux系统负责接收硬件中断,再由系统调用中断服务子程序,而不是直接从arm的中断向量表中调用这部分程序。在模块初始化时已经利用request_irq( )函数注册了设备中断,所以当irq(中断请求)产生时,isr(中断服务例程)运行。在中断服务程序中,首先要读取sja1000的中断寄存器ir的值,识别中断源,比如当接收中断位ri为1则说明是接收中断,进而调用接收函数来接收数据。当cpu读取这个只读存储器时,除了ri位外的所有位都被复位。
⑷缓冲区操作
sja1000内部设有发送缓冲器txb(13个字节),接收缓冲器rxb(13个字节)和rxfifo(64个字节)。其中txb是cpu和bsp(位流处理器)之间的接口,存储发送到can网络上的完整报文。接收缓冲器是接收过滤器和cpu之间的接口,用来接收和存储can总线上的报文,rxb是rxfifo的一个窗口,可被cpu访问。为了提高收发效率,在驱动中开辟软件缓冲区,大小可以根据需要设置,将大量数据经过软件缓冲区后再进行处理。在操作软件缓冲区时,采用生产者/消费者模型,分别设定数据存入与读出的指针,并且利用memcopy函数完成对帧数据的操作。比如读取数据时,首先在操作模式下将sja1000中起始地址为16的rxb数据读入一个数组,经过一些必要判断,再将此数组中的数据由memcopy函数传入指定的软件缓冲区。硬件缓冲与软件缓冲间一次传递一帧数据,帧有标准帧与扩展帧之分。
3.2 shell应用程序的实现
shell应用程序主要是为用户提供一系列方便直观的接口,使得用户不必了解硬件工作的细节,不必研究驱动的具体实现,而仅仅根据自身的需要,通过一些简单明了的命令来完成所要求的任务。本文就将在shell应用程序中实现以下命令功能:
init初始化寄存器,rsja读取寄存器值,wsja写寄存器,gfrm收数据帧,sfrm发数据帧,conf配置滤波器,help帮助,exit退出。
在主函数main中,通过int open(const char * filename, int mode)函数打开can设备,得到一个文件句柄fd,将此句柄传递给shell函数,这样就可以在各个命令函数中对can设备进行操作,比如可以在函数int write_sja1000(int fd,unsigned char addr, unsigned char value)中使用ioctl(fd,sja_write,®_data)来实现对sja1000寄存器的写操作。
在shell应用程序中,可以设定一个字符数组char cmd[5],通过fgets(cmd,5,stdin)来接收用户键入的命令,再经过strcmp函数辨认出用户的命令类型,执行相关操作。为避免输入缓冲区出现垃圾导致命令识别出现错误,需要及时清空输入缓冲,而当gcc中fflush函数无效的情况下,则可以通过while((c=getchar())!='n'&&c!=eof){ }来清空输入缓冲。
完成了所有驱动以及应用程序的编写后,用makfile文件制定编译规则,然后根据规则进行编译,调试成功后可将二进制代码通过超级终端下载到板子运行,至此结束所有工作。
4.结语
本文提供了一种ep9315与can控制器sja1000的接口方案,详细分析了linux操作系统下驱动与应用程序的原理及开发流程,实现了can设备通信,并在实际应用和测试中证明了该设计的正确性和可靠性。由于嵌入式linux的众多优势以及can的实时性,易用性,可靠性等优点,它们将在工业控制及生活的各个领域具有更广泛的应用前景。
本文作者创新点:利用ep9315与sja1000实现can总线通信,完成了由硬件连接,底层驱动以致上层应用软件的所有工作,利用软件方便稳定的控制can通信。

超大电池+高颜值:魅蓝note3,比华为便宜3000元啊!
用一个仅有14条I/O腿的FPGA最小系统模块实现几种仪器的功能
黑客频繁攻击新冠疫苗冷链企业,是利益还是阴谋?
中筑天佑以2.35亿元中标佛山夜间经济环境营造项目
版权官司:苹果败诉给 “虚拟 iPhone”生产商
Linux环境下实现ARM9的CAN总线通信
R&S发布SMA100B模拟信号发生器,可提供更为纯净的信号
网络及内容是阻碍5G应用发展的两大绊脚石
物联网最具代表性的应用是什么
“十四五 ”瞄准半导体产业链关键环节,中国汽车芯如何破局?
黑胶唱片还有用么
韩国区块链公司MVL在新加坡推出了打车应用
电视开机广告过长的秘密
5G+VR开启行业应用新场景
骨传导耳机的工作原理是什么?骨传导耳机有什么优缺点?
IPAD商标战越演越烈 深圳唯冠斥IPAD应下架
你有这些嵌入式硬件电路设计的基本功吗?
MySQL高级进阶:索引优化
原厂供应有感三相直流无刷电机驱动控制芯片CK3362N/S
中国移动发布了2020年5G多模路测软件和5G多模扫频仪集采公告