基于VxWorks操作系统实现PC/104-CAN适配卡的驱动系统设计

来源:单片机与嵌入式系统应用,作者:解月工,秦龙勇,谢拴勤,彭卫东
1 pc/104-can适配卡的硬件结构
pc/104-can适配卡主要由can控制器(sja1000)、光电隔离(6n137),收发驱动器(82c250)及译码电路组成。编程主要了解的是控制器sja1000。can适配卡原理如图1所示。
2 can地址译码和中断选择
系统104主板的cpu为486dx,其对接口板访问有两种方式:内存映射和i/o访问。i/o寻址采用专门的指令,每次只能传送单个字节。内存映射方式可以访问较大的地址空间并且指令丰富,便于实现快速交换数据。本文讨论的can卡采用存映射模式工作,与486dx接口是104总线,它与 isa总线兼容。对于intel x86体系的cpu,isa可以映射的空间为0xc8000~0xeffff。使用比较器和地址选择开关组成可选端口地址译码电路,通过开关选通内存映射基地址(c8000h、c9000h、ca000h、…、ef000h),以避免与其它器件冲突。can偏移地址分配如下:
00~ffh sja1000的寄存器;
100h~1ffh 对该范围内的任意地址进行写操作,均可导致can硬件复位。
sja1000的int引脚通过跳线选择irq3~7、irq9~12或irq15中的一个,避免与其它的适配卡冲突。
3 pc/104-can适配卡驱动实现
3.1 vxworks驱动概述
vxworks操作系统有两种方式实现驱动。第一种方式是,把设备驱动程序作为独立任务实现,直接在顶层任务中实现硬件操作,完成特有专用的驱动程序。第二种方式是,vxworks的i/o系统将设备程序作为内核过程实现。这种方式便于实现i/o子系统的层次模型,便于文件系统一起把设备作为特殊文件处理,提供统一的管理、统一的界面和统一的使用方法,并把设备、文件及网络通信组织成为一致的更高层次的抽象,为用户提供统一的系统服务和用户接口。我们和这种驱动方式。
作为i/o系统和硬件设备之间的连接层,vxworks驱动就是屏蔽硬件操作,为i/o系统提供服务。实现一个完整的驱动,必须了解vxworks下i /o的三个基本元素:file、driver和dervice。file是为用户提供访问设备的统一接口;driver是实现具体的基本控制函数,也就是实现i/o系统所需要的接口;而device则是一个抽象的硬件设备,是一系列的结构体、变量和宏定义对实际物理设备的定义。一般而言,实现一个驱动应该有三个基本的步骤:①用编程语言完成对实际物理设备的抽象;②完成系统所需要的各类接口及自身的特殊接口;③将驱动集成到操作系统中。之后还有一些调试工作。
3.2 vxworks i/o系统驱动程序框架
vxworks为各种设备(包括字符设备、块设备、虚拟设备及网络设备)提供统一的访问接口,包括七种基本的i/o函数:open(filename、flags、mode),create(filename、flags),read(fd、&buf、 nbytes),write(fd、&buf、nbytes),ioctl(fd、command、arg),close(fd)及 remove(filename)。i/o系统所起的作用就是,把用户请求分配到与设备对应的驱动例程中去。vxworks系统中有一个驱动程序列表,其形式如表1所列。
表1 设备驱动列表(调试时可利用iosdrvshow()查看)
i/o系统的可动态调用iosdrvinstall()函数将设备的驱动例程(即xxopen()、xxclose()、xxread()等)加入到设备驱动列表中,如图2所示。
同样,系统中有一个设备列表,每个设备对应于设备列表中的一项,每一项包括设备名称和设备驱动号,同时包括一个设备描述的结构。该结构第一个变量是dev_hdr类型的变量dev_hdr。
dev_hdr的定义如下:
typedef struct
{
dl_node node; /*设备列表节点*/
short drvnum; /*驱动号码*/
char *name; /*设备名*/
}dev_hdr;
系统调用iosdevadd(),可以将设备加入到设备列表中。系统中将驱动和设备联系起来的就是文件描述符列表,每个文件描述符列表除了包括驱动号、设备id外,还包括文件名、可用标志和指向dev_hdr的指针。系统每次成功执行open(),返回一个文件描述符,这样对于设备的 read()、write()及ioctl()就可以通过文件描述符进行。
文件描述符表(调试时调用iosfdshow()查看)如下:
i/o系统的整体结构如图3所示。系统启动时(一般挂接在usrroot()),xxdrv()和xxdevcreade()便将设备及其驱动加入相应的列表中。
3.3 设备驱动程序的访问过程
下面以can驱动程序为例,说明驱动程序的访问过程。(假定设备名“/can/1”并且以can设备驱动程序为例,上述中的xx在这里用can代替。)
①fd=open(“/can/1”,o_rdwr,0644)
②i/o系统在设备列表中寻找设备名为/can/1的设备项,找到相应的设备驱动号。
③i/o系统在文件描述符中保留一个文件描述符空间。
④i/o系统在设备驱动列表中找到对应的canopen(can_dev*pcan_dev,ubyte*remainder,int flags),该驱动例程返回设备描述符的指针。
⑤i/o系统将设备描述符的指针存储在文件描述符列表的device id,同时将对应的设备驱动号存储在文件描述符的driver num项。最后i/o系统返回该描述符项的索引(即为fd)。
⑥这样应用程序中的read()和write()等函数调用就可以根据fd找到相应的设备驱动号,进而找到相应的驱动例程。
4 can驱动程序的实现
can驱动程序的实现即是完成下面七个函数的编写。下面简要介绍其完成的功能,并用伪指令进行说明。
int drv_num; ;/*驱动号码*/
typedef struct {
dev_hdr pcanhdr; /*这个数据结构必须放在设备描述符的最初部分*/
/*其余与驱动有关数据*/
}can_dev; /*can设备描述符*/
can_dev can_chan_dev;
status candrv(void){
完成驱动的一些初始化;
intconnect(); /*连接所选的irq与中断处理函数*/
sysintenablepic(); /*486dx允许中断*/
drv_num=iosdrvinstall(canopen,null,canopen,canclose,canread,canwrite,canioctl);/*将设备驱动例程装入设备列表中*/
}
/*iosdrvinstall()将设备的can驱动例程加入设备驱动列表中,7个参数为7个驱动例程的进入点(entry point),如果没有某个例程,则传递null。*/
status candevcreate(){
完成一些设备初始化
iosdevadd (&can_chan_dev.pcanhdr,“can0”,drv_num);/*将设备放入设备驱动列表中*/
}
int canopen(can_dev *pcan_dev,ubyte *remainder,int flags){
can卡硬件复位
can卡关中断
can卡进入软件复位模式
设置can卡工作寄存器,如接收码寄存器和屏蔽码寄存器等
can卡开中断和进入操作模式
return((int)pcan_dev); /*注意必须返回设备描述结构指针*/
}
int canread(int can_dev_id,ubyte * buf,int nbytes){
等待信号量(该信号量由中断处理例程释放)
从接收缓冲区读取数据
释放接收缓冲
返回接收数据数量
}
int canwrite(int can_dev_id,ubyte* buf,int nbyte){
查询发送缓冲是否可用
向发送缓冲区写数据
命令发送
查询发送完成标志
返回发送数据数量
}
void interrupt_handle_routin(int arg){
处理中断事件
发送(释放)信号量
}
限于篇幅,其它函数略。
5 can驱动调试
硬件驱动的调试是件十分麻烦的事,经验十分重要。这里简要介绍几个帮助调试的函数。
①可以调用iosdrvshow()、iosdevshow()及iosfdshow()查看相关内容,判断并将驱动及设备中入相应列表。
②使用logmsg()现实相关内容,以定位错误。
初期调试,示波器和信号灯是非常有用的,可以确定硬件的工作状况,从而有助于发现程序中的错误。
6 小结
笔者采用两种方式完成了can卡驱动。相对于第一种(笔者亦完成),第二种方式——vxworks的i/o系统将设备程序作为内核过程实现,大大减少了系统的开销,实时性和可靠性有了很大的提高,并且为用户提供了统一的接口,使用十分方便。
开发驱动程序,辅助工具是非常有用的。windows下的开发工具就比较多,而在vxworks下开发驱动的工具相对较少。windriver 是一款不错的开发工具,可以开发vxworks下的驱动程序(也可以开发其它操作系统下的驱动程序)。正确、熟练地使用这些辅助工具,会使开发工作事半功倍。


Arduino篇—点亮LED
设计师点评,荣耀9、三星S8、锤子坚果Pro谁更惊艳
迎向新版蓝牙5.4标准的必备设计知识!
传统巨头在改变,通用凯雷德配备38英寸OLED曲面显示屏
Leader烟机智能屏将实现厨房家电的智慧互联
基于VxWorks操作系统实现PC/104-CAN适配卡的驱动系统设计
STM32数据手册开发实现按键输入功能
什么是拉电流?什么是灌电流?它们为什么能够衡量输出驱动能力呢?
灵活运用Python中numpy库的矩阵运算
物联网技术能给环境危机带来什么好处
谷歌Pixel3评测 饱含满满的国际大厂范儿
图解无刷电机原理
用于电动汽车的48V系统
Mini/Micro LED的成本将会快速下降,从而在更多的应用领域落地
国内首个IT云服务智能工业园区落户甘肃
NVIDIA DOCA 1.3增强网络和安全基础设施服务
南大光电:公司光刻胶产品客户验证正在顺利推进
uc3842典型电路
兆易创新荣获北京市科学技术奖一等奖
工控控制系统应该如何应对等保2.0的新要求