2.3.3 函数库ttyDrv.c
前面主要分析了vxWorks系统IO设备管理的通用数据结构及其操作,这个通用接口既适用于串口类设备、又适用于网络设备等等。对于串口这类设备来说,其驱动又有其独有的要求,如收发缓存的管理,波特率的设置等等。同样,作为串口驱动的部分,也可以分为与硬件相关部分和与硬件无关部分。
VxWorks操作系统的串口驱动与硬件无关部分主要有两个函数库来实现,一是ttyDrv函数库,主要用于7个通用函数中的5个函数的具体实现,另一个是tyLib函数库,主要用于处理收发缓冲区的处理。另一方面,从结构TYCO_DEV来看,tyLib的主要数据结构TY_DEV变量包含在结构TYCO_DEV,因此其层次关系可以用图2.12所示。
图2.12 函数库ttyDrv与tyLib的层次关系
函数库ttyDrv主要通过结构SIO_CHAN访问底层函数,在结构TYCO_DEV中有一个SIO_CHAN结构变量指针,该变量指针指向底层的操作函数。如图13所示。
图2.13 ttyDrv库与底层库的函数接口
首先分析ttyDrv函数库,这个函数库比较简单,直接分析各个函数。
1. STATUS ttyDrv (void)
函数ttyDrv主要调用了函数iosDrvInstall完成了7个函数的安装,对串口来说,系统并不要完全安装这7个函数,比如delete函数,如果操作系统不要求delete串口驱动,那么这个函数也就不需要了。实际上ttyDrv函数主要安装了基本操作函数,如图2.14。
图2.14 函数ttyDrv主要安装的函数
这些函数中有ttyOpen、ttyClose、ttyIoctl是由函数库ttyDrv.C提供的,其他函数如tyRead、tyWrite则是由函数库tyLib提供的。
2. STATUS ttyDevCreate
(
char * name,
SIO_CHAN * pSioChan,
int rdBufSize,
int wrtBufSize
)
这个函数为一个tty设备创建了一个TYCO_DEV数据结构并进行初始化(包括硬件的初始化)。其中pSioChain是底层串行通道描述符(SIO_CHAN结构变量)的地址。rdBufSize和wrtBufSize为读写缓冲区的大小。
ttyDevCreate函数在执行过程中调用了函数tyDevInit对tyLib库进行了初始化。注意调用函数tyDevInit的最后一个参数ttyStartup,这个函数对底层操作函数(pSioChan)->pDrvFuncs->txStartup进行了封装,也就是说只有函数ttyDrv直接与底层硬件操作函数向关联,而tyLib库则完全被保护在了硬件无关层(参见图2.12)。
ttyDevCreate()函数操作的数据结构如图2.15所示。同时它指定了串口的处理模式为中断模式(另一种为轮询模式)。
图2.15 ttyDevCreate()函数操作的数据结构
注意这个函数和ioLib库中的create函数是完全不同的概念,该函数的调用应该在create之前。
3. LOCAL int ttyOpen
(
TYCO_DEV * pTyCoDev,
char * name,
int flags,
int mode
)
打开一个ttyDrv串行设备。所谓打开设备就是使其处于准备收发数据的状态,对i8250串口控制芯片来说就是设定计算机准备接收(DTR)和请求发送数据(RTS)的状态。
注意:每调用一次函数ttyOpen,该pTyCoDev->tyDev.numOpen就会自动加1,表明该设备打开的次数。
4. LOCAL int ttyClose
(
TYCO_DEV * pTyCoDev
)
关闭一个ttyDrv设备。所谓关闭设备就是就是关闭其收发数据就绪的状态。
注意:每调用一次函数ttyClose,pTyCoDev->tyDev.numOpen就会自动减1,表明该设备打开的次数。
5. LOCAL int ttyIoctl
(
TYCO_DEV * pTyCoDev,
int request,
void * arg
)
对硬件设备的控制操作。
request是一个比较广义的操作,包含的种类繁多,而且对同样的操作,对不同的函数库来说,参数也可能会有所不同,如波特率设置,在ttyDrv库request为FIOBAUDRATE,这个参数在iosLib.h中定义,而在sioLib库中该参数为SIO_BAUD_SET,因此需要进行参数的转换;另一方面sioIoCtl函数和tyIoCtl函数处理的职责是不同的,因此需要首先尝试调用sioIoCtl函数,如果无此操作则尝试tyIoCtl函数。
6. LOCAL void ttyStartup
(
TYCO_DEV *pTyCoDev
)
发送数据函数。直接调用底层的发送函数。
在函数ttyDrv中调用iosDrvInstall函数安装了两个函数tyRead和tyWrite,这两个函数并在函数库ttyDev中,而是在tyLib库中。主要完成收发缓冲区的处理,下面要进行tyLib库的分析。