微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > vxworks嵌入式操作系统下串行设备驱动程序开发思路

vxworks嵌入式操作系统下串行设备驱动程序开发思路

时间:10-09 来源:互联网 点击:

= i8250SioDrvFuncs;/*初始化CHAN结构,挂接接口函数列表*/

i8250InitChannel(pChan); /* reset the channel */

}

由上面挂接的函数可以看出,i8250驱动主要实现了三个功能:read、write、ioctl,而并没有实现所有和七项功能。同时,值的注意的是,对同一种设备的驱动只需挂接一次。

同时ttyDrv通过SIO_DRV_FUNCS使用xxDrv(i8250Drv)提供的服务,而xxDrv通过回调函数(本例中是由i8250CallbackInstall()安装的tyIRd()、tyITx())完成ttyDrv提出的请求。原理如下图示:

i8250InitChannel()

本函数的主要作用是初始化特定的CHAN所描述的信道。具体分析如下。

statIC void i8250InitChannel

(

I8250_CHAN * pChan /* pointer to device */

)

{

int oldLevel;

ldLevel = intLock (); /*关中断进入临界区*

(void) i8250BaudSet(pChan, I8250_DEFAULT_BAUD);/*设置信道的波特率*/

…………………………………

intUnlock (oldLevel); /*开中断响应,出临界区*/

}

⑵ 挂接中断服务程序

对i8250的硬件初始化完成后,接着挂接相关的中断服务程序。主要有sysSerialHwinit2()函数完成。需要注意的是,挂接中断应放在系统初始化的最后,主要是因为中断挂接函数iNTCONnect()需要调用malloc()函数,如果在系统的内存分配还未初始化前调用,则会出错。下面请看源代码:

void sysSerialHwInit2 (void)

{

int i;

for (i=0;i

if (i8250Chan[i].int_vec)

{

(void) intConnect (INUM_TO_IVEC (i8250Chan[i].int_vec), i8250Int, (int)i8250Chan[i] );

sysIntEnablePIC (devParas[i].intLevel);

}

}

其中,宏INUM_TO_IVEC的作用是把中断号转为中断向量。i8250Int是指向输入/输出中断处理函数的指针。描述相应硬件的结构i8250Chan为函数i8250int()的入口参数。

至此,设备硬件的初始化、相关的低层函数的挂接、中断初始化基本完成。开始进行下一步,将设备的驱动函数安装在Driver Table 中。

⑶ 与上层标准输入/输出函数的挂接

在此处I/O系统通过调用ttyDrv()(在没有定义INCLUDE_TYCODRV_5_2的情况下)将相应驱动函数添加到Driver Table中,从而完成与上层标准输入/输出函数的挂接。

由上图知,iosDrvInstall()函数在Driver Table中挂接的函数是tyWrite()和tyRead(),而不是我们实际编写的输入/输出函数。其具体的调用过程是:

① 当用户调用write函数进行写操作时,根据相应的fd调用在Driver Table中注册的函数tyWrite(),此函数的作用是将用户缓冲区的内容写入相应的输出ring buffer,当发现缓冲区内有内容时,开始调用回调函数tyITX(),从ring buffer读取字符,由I8250Startup()启动中断输出,最后由设备的输出中断服务程序(在本例中调用的是sysOutbyte())将字符发往指定的串口。

② 当串口接收到数据时会调用输入中断服务程序(在本例中是sysInbyte()),将输入的字符写入指定的缓冲区。然后由回调函数tyIRd()将缓冲区的内容读入ring buffer,当用户调用read函数进行写操作时,会根据相应的fd调用在Driver Table中注册的函数tyRead(),此函数会将ring buffer中的内容读入用户缓冲区。

关于具体的中断输入/输出函数如何调用,本文不做详细分析,请参阅i8250int()及i8250Startup()。

对于输入/输出控制函数ioctl()的挂接,则是直接将命令传到由用户编写的i8250ioctl()函数,其具体的实现代码与驱动的设计思路无紧密的联系,本文也不做具体分析。

⑷ 具体设备与相关驱动的挂接

当Driver Table中相应的驱动函数挂接完成,开始编写驱动程序的最后一步:在Device Table中加入设备,完成具体设备与相关驱动的挂接。此项工作是由ttyDevCreat()函数完成的。本函数主要实现以下功能:

① 分配并初始化一个device descriptor。

② 通过调用tyDevInit()初始化tyLib。此处主要完成输入/输出ring buffer的创建、建立用与相关函数的信号量、初始化selectLib。

③ 调用iosDevAdd()将串口设备加入Device Table。对于设备特性的描述信息是由sysSerialChanGet()函数得到,并以参数形式传入的。

④ 为底层设备安装回调函数,在本例中是为i8250CHAN 安装tyIRd()、tyITx()两处回调函数。

⑤ 开中断,设备开始以中断方式工作。

至此,驱动程序的分析全部完成。与挂接驱动函数不同,在安装设备的过程中,无论设备相同与否,有几个设备则上述过程需调用几次。以上各函数的加载主要在usrinit()函数中完成。

3. 结束语

需要说明的是,在VxWorks下,设备驱动程序既可

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top