实时系统VxWorks下设备驱动程序的编写

来源:互联网 发布:网络大电影广告植入 编辑:程序博客网 时间:2024/05/01 02:59

VxWork下设备驱动程序存在于硬件设备和上层应用程序之间。设备驱动程序直接管理硬件设备,并对上层应用程序提供屏蔽了地层硬件特性的接口调用。

驱动程序只提供几个低级的I/O函数完成简单的数据输入和输出功能,而其它具体的高级协议,如面向字符设备的协议和面向块设备的协议,则是由与设备无关的I/O系统完成。I/O系统为用户的I/O请求寻找具体的驱动程序。

I/O系统管理着驱动程序,把应用程序的I/O请求转发给合适的驱动程序进行处理。

I/O系统为驱动程序维护着三张表,

(1)文件描述符列表FD TABLE,维护着已打开设备的句柄,驱动该设备的驱动程序号,设备相关参数的指针这三者的对应关系。

(2)设备描述链表DEVICE LIST,维护着系统中存在的设备号,驱动该设备的驱动程序号,设备相关的参数的指针三者的对应关系。

(3)驱动程序列表DRIVER TABLE,维护着驱动设备的驱动程序号,和该设备对应的七个基本I/O操作的函数(如xxOpen..等)的入口地址这两者的对应关系。

I/O系统对这三个表的操作大致过程为:

当调用creat(..)或oPen(...)时,首先在设备描述链表中根据设备名找到相应的项(若为 create,则创建响应的表项),根据驱动程序号找到底层实现代码xxCreate(..)或xxOpen(...),I/O系统将驱动程序号及xxCreate(...)或xxOpen(...)返回的指向设备相关参数的指针添入文件描述符列表中,最后,返回在文件描述符列表中添加的项在该表中对应的序号,即文件句柄,提供给后续的I/O操作使用。

当调用read(...)或write(...)时,根据文件句柄,在文件描述符列表中找到对应的表项,得到操作该设备的驱动程序号,I/O系统再根据驱动程序列表得到响应的底层驱动实现函数xxRead(...)或xxWrite(...)入口地址,调用相应的与设备相关的底层操作代码。

字符设备的驱动程序和I/O系统直接作用。字符设备调用驱动安装函数iosDrvInstall(...)在VxWorks中安装驱动程序。该函数有7个参数,分别指向驱动程序提供的7个标准I/O函数creat(...),delete(...),open(...),close(...),read(...),write(...),ioctl(...)。有些函数不一定实现,对应的参数可以为NULL,iosDrvInstall(...)只为驱动程序在驱动函数列表中分配了一个 位置,要使用驱动函数还必须调用安装设备函数iosDrvAdd(..),把设备名和驱动程序号写到数据结构DEV_HDR中,并把它加入到系统的设备描述键表中。

块设备的驱动程序不与I/O系统直接作用,它是通过文件系统与I/O系统作用的。文件系统把自己作为一个驱动程序装载到I/O系统中,并把请求转发给实际的设备驱动程序。块设备的驱动程序不使用isoDrvInstall(...)来安装驱动程序,而是通过初始化块设备描述结构BLK_DEV或顺序设备描述结构SEQ_DEV,来实现驱动程序提供给文件系统功能。块设备也不调用设备安装函数isoDrvAdd(...),而是调用文件系统的设备初始化函数如dosFsDevInit(...)等。

一般的,驱动程序包括三部分:初始化部分,函数功能部分和中断服务函数ISR。

初始化部分初始化硬件设备,分配设备所需的资源,完成系统相关的设置。对于字符设备来说,首先调用iosDrvInstall(...)安装驱动程序,把中断向量和中断服务函数挂上,然后调用iosDrvAdd(...),加载驱动程序到I/O系统。对于块设备来说,首先把中断向量和中断服务函数挂上,在内存中分配一个设备结构并初始化,用户使用该设备部分,在调用设备的创建函数返回一个BLK_DEV结构的指针,供文件系统的初始化函数使用。

函数功能部分完成系统指定的功能。对于字符设备,就是7个标准I/O函数;对于块设备,则是BLK_DEV或SEQ_DEV结构中指定的函数。

中断服务程序是实时系统的重要组成部分,系统通过中断机制来了解外部事件,并做出响应。实时系统的反应速度取决于系统对中断的响应速度和中断处理程序的处理速度。因此,中断服务程序的处理时间应尽量短。所用的中断服务程序共享一个堆栈,没有任务控制块,所以,在中断服务程序中不能使用可导致阻塞的函数,如printf(...),semTake(...)等。如果希望在中断服务程序中输出一些信息,可以使用sysLOg(...),该函数是非阻塞的,可以接收7个参数。中断服务程序可以 使用semGive(...)与其它的非中断服务程序进行通信。理想的情况下,一个中断服务程序仅调用一个semGive(...)系统调用,也就是说,中断服务程序的主要功能是发起一个任务并完成必要的处理。为提高中断服务程序与任务的合作性能,最好的机制是信号量。

VxWorks系统中打印并口驱动程序的实现

(1)函数功能部分

根据打印并口的特点,并口驱动程序中要实现的基本的I/O函数应该是lptOpen(...),lptWrite(...)和lptIoctl(...),这三个函数的声明分别如下:

LOCAL int lptOpen(LPT_DEV *pDev, char *name,  int mode);

LOCAL int lptWrite(LPT_DEV *pDev, char *pBuf, int size);

LOCAL STATUS lptioctl(LPT_DEV *pDev, int function, int arg);

三个函数的实现很简单,其中最主要的是lptWrite(...),在此函数中可以使用轮询方式,也可以采用中断方式。

(2)初始化部分

初始化函数声明为:STATUS lptDrv(int channels, LPT_RESOURCE *pResource);

该函数完成了打印并口的初始化,其中调用函数intConnect(...)和iosDrvInstall(...)的具体形式为:

(void)intConnect(  (VOIDFUNCPTR*)INUM_TO_IVEC(pResource->intVector),(VOIDFUNCPTR)lptIntr, (int)pDev);

lptDrvNum = iosDrvInstall(lptOpen, (FUNCPTR)NULL, lptOpen, (FUNCPTR)NULL, NULL, lptWrite, lptioctl);

设备的创建函数声明为:STATUS lptDevCreate(char *name, int channel);该函数将创建标志置为TRUE,然后调用函数iosDevAdd(&lptDev(channel).devHdr, name, lptDrvNum)将创建的设备加入到I/O系统中。

中断服务程序实现部分

对于答应并口,中断服务程序可以这样实现:

LOCAL void lptIntr(LPT_DEV *pDev)

{

          pDev->inservice = TRUE;

          pDev->intCnt++;

         semGive(&pDev->syncSem);

          pDev->inservice = FALSE;

}

 

 

 

原创粉丝点击