1、VxWorks设备驱动结构
首先在终端输入iosFdShow,此命令用来显示已经打开的设备信息。
- fd 是设备描述符,open函数返回以后供read, write等函数使用。
- name 设备的名字。
- drv 对应的驱动程序索引。
在终端输入 devs:
- drv 对应上一幅图中的drv。
- name 设备名称。
在终端输入iosDrvShow
可以看到,该表通过drv索引到7个函数。
以上就是vxworks设备驱动程序的三张表。这三张表是怎么生成的呢?首先我们来看一下驱动创建的过程:
这里要用到两个函数iosDrvInstall和iosDevAdd。在vxworks的bsp文件中执行iosDrvInstall,会返回一个drv,这个drv就是上面三张表中的drv。也就是说,每次向内核添加一个驱动时,内核就会返回一个设备驱动的索引。
在来看一下 iosDevAdd (DEV_HDR * pDevHdr, const char * name, int drvnum)函数。调用该函数需要传入三个参数,drvnum是iosDrvInstall返回的,name就是设备的名字。重点来分析下DEV_HDR * pDevHdr,该结构用来创建设备列表。该结构在系统中做如下定义
typedef struct
{
DL_NODE node; //设备节点
short drvNum; //驱动号
char * name; //设备名称
}DEV_HDR;
在使用该函数时候,需要创建一个关于DEV_HDR的实例。如下:
typedef struct
{
DEV_HDR devHdr;
int ix;
BOOL Opened;
BOOL RdReady;
BOOL WrReady;
}gh_DEV;
int bsp_hello(char *devName)
{
printf("hello world\n");
LOCAL int ghDrvNum=0; //driver index num
ghDrvNum = iosDrvInstall(testOpen, NULL, testOpen, testclose, testread, testwrite, NULL);
gh_DEV *pghDev = (gh_DEV *)malloc(sizeof(gh_DEV));
bzero(pghDev,sizeof(gh_DEV));
pghDev->WrReady= 1; /*Initial gh_Dev*/
iosDevAdd(&pghDev->devHdr,devName,ghDrvNum);
return 0;
}
通过以上的步骤,把三张表联系到了一起。
在iosDrvInstall(testOpen, NULL, testOpen, testclose, testread, testwrite, NULL);函数中注册了设备驱动的接口函数。
以下是所有代码:
#include <stdio.h>
#include "vxworks.h"
#include "tasklib.h"
#include "syslib.h"
#include "config.h"
#include "vmlib.h"
typedef struct
{
DEV_HDR devHdr;
int ix; //
BOOL Opened;
BOOL RdReady;
BOOL WrReady;
}gh_DEV;
int testOpen(DEV_HDR *path ,int opt , int flags)
{
gh_DEV* rel = (gh_DEV *)path;
printf("enter %s \n",__FUNCTION__);
return (int)rel;
}
int testclose(int devid)
{
printf("enter %s \n",__FUNCTION__);
}
int testread(int fd ,char *buf ,size_t nbyte)
{
printf("enter %s \n",__FUNCTION__);
return 0;
}
int testwrite(int fd ,char *buf ,size_t nbyte)
{
printf("enter %s \n",__FUNCTION__);
return 0;
}
int bsp_hello(char *devName)
{
printf("hello world\n");
LOCAL int ghDrvNum=0; //driver index num
ghDrvNum = iosDrvInstall(testOpen, NULL, testOpen, testclose, testread, testwrite, NULL);
gh_DEV *pghDev = (gh_DEV *)malloc(sizeof(gh_DEV));
bzero(pghDev,sizeof(gh_DEV));
pghDev->WrReady= 1; /*Initial gh_Dev*/
iosDevAdd(&pghDev->devHdr,devName,ghDrvNum);
return 0;
}
这部分代码只是简单的实现了应用层通过调用统一的系统调用接口,open,read等函数,来实现对驱动驱动程序的抽象。并没有涉及到实际硬件的操作。(其实有了接口以后,硬件的操作和单片机一样了),之后会介绍驱动和中断的链接。
以上代码需要注意的是,在open函数中通过获取设备的描述结构,返回给应用层一个设备描述。供其他系统调用使用。