VxWorks驱动移植基础知识

VxWorks驱动架构:

一、在最新发布的VxWorks6.x版本中,devicedriver可以通过两种方式来实现

1、 VxBus-enabled devicedrivers

这种架构下编写的driver为OS和设备定义了一系列标准接口来和driver交互

2、as legacy(pre-VxBus) device drivers

这种结构下编写的驱动没有为OS和设备提供标准接口

VxBus驱动:

 

什么是VxBus

(类似Linux的设备树):总体上来说,它是指一种在最小BSP的支持下,为VxWorks中的设备驱动提供支持的特定框架。包括以下几点功能:

1)  提供设备驱动匹配设备的功能。

2)  提供驱动获取硬件设备的机制。

3)  提供软件环境的其他部分访问设备的功能。

4)  其他为了在VxWorks系统中把设备驱动封装为函数需要的函数(and other functionality required in order for device drivers to befunctional in a VxWorks system.)

另外VxBus有时候也指VxWorks操作系统的一系列通过workbench使用的Component,core VxBusfunctionality是一个Component,每个VxBus驱动也都是一个Component,VxBus支持的模块也是Component,每个Component可以单独的在workbench中选择。在VxWorks6.2版本以前设备驱动还没有整合到VxWorks工程配置中,每次添加或者去除支持都需要通知BSP和驱动,这样在添加或者删除驱动时需要更多精力来管理工程,VxWorks6.2版本以后就不需要这些操作。

Component这个概念在VxWorks中非常重要,VxWorks的裁剪和添加模块都是以Component为单位进行的,我们自己编写的每个设备驱动都会被作为一个单独的Component,然后通过配置文件选择是否将这个设备驱动添加到VxWorks内核中。

 

VxBus Device Drivers:

device:指硬件的一位(这个还没搞清楚)

driver:执行代码和根据硬件设备配置OS的信息

instance:驱动和设备配对后组成一个instance

VxBus驱动与设备的匹配:

驱动和设备的匹配,硬件的可用性

1. 首先VxBus确定注册的bus type是否与设备所在的bus相同

2. 其次,VxBus运行match函数

3. 最后,如果驱动提供了Probe函数,这个函数会被调用来让驱动验证是否能和被发现的硬件正常工作。

第一步和第三步通常没有变化,然而根据bus_type的不同,第二步的变化会很大

 

当使用一个驱动函数的时候,发出申请的模块会去查询一个或者全部instance,这个请求可以是请求如何完成一个动作的信息也可能是一些驱动执行某些动作的请求。

如果某个instance支持这个模块,就会返回一个响应。

VxWorks驱动移植基础知识_第1张图片

 

图中的middleware是指VxWorks的中间件,中间件是介于操作系统和应用程序之间的一个软件层,运行于操作系统上。

设备驱动注意点:参考《vxworks_device_driver_developers_guide_vol1_6.7》

实时性和内存分配(codesize)都是VxWorks驱动考虑的重要部分

VxBus设备驱动初始化阶段

驱动的生命周期:

从VxWorks目标启动到驱动和系统无关为止

1、Driver Initialization Sequence

VxWorks驱动移植基础知识_第2张图片

 

 

 

1、  early boot process

Device drivers do not play any role in the early boot process.Depending on which

processor architecture you are working with, the CPU typically jumpsto a

specified address at power-on and starts executing instructions.Those instructions

typically come from ROM or flash.

These early instructions initialize the memory controller and CPU,then start the

procedure for initializing VxWorks.

这一阶段不会对设备驱动进行操作。

2、  hardware discovery

sysHwInit()是在BSP提供的函数,他在系统初始化上一阶段被调用,然后调用hardWareInterFaceInit():vxbUsrCmdLine.c(target\config\all)    399510     2016/8/4 星期四。hardWareInterFaceInit()函数首先初始化硬件内存申请机制,它在系统内存池初始化完成之前为设备驱动的内存申请提供了上下限。

然后调用hardWareInterFaceBusInit()函数,这时个别驱动通过注册到VxBus上,已经被激活。

首先被激活的驱动之一是PLB(processor local bus)设备驱动.

Bus controller drivers负责决定现在系统中存在哪些硬件设备,PLB设备不支持设备发现,但是BSP驱动可以读取BSP提供的设备信息表,然后直接将其连接到BUS上,这样VxWorks可以知道什么设备直接连接到了PLB,但是现在系统还无法知道其他BUS上的设备。

3、  driver registration with the OS

hardWareInterFaceInit()调用hardWareInterFaceBusInit(),这个函数最核心功能是设备和通用模块的注册,这个阶段每个驱动都会调用一个注册函数vxbDevRegister(),告诉VxWorks系统现在驱动有效并且提供驱动的相应的信息。

4、  phase 1

在设备和驱动匹配成功形成一个instance后,VxWorks会检查在驱动调用vxbDevRegister()时提供的注册结构体。

       这个结构体包含一些驱动初始化入口函数,第一个入口是devInstanceInit()函数(比如vxbOmap35xxIntCtlrInstInit())devInstanceInit( )函数是在VxBus初始化阶段一调用的,这是第一次将应将设备变得有意义。然而设备类例如中断控制器和串口驱动,在devInstanceInit()完成之后还有一些特殊的需求,至少,需要保证你的devInstanceInit()函数禁止了设备的中断。

 

5、  kernel startup

After all drivers have registered with VxWorks, thehardWareInterFaceBusInit( )

and hardWareInterFaceInit( ) routines return, sysHwInit( ) completesany

non-VxBus driver initialization and returns. After sysHwInit( ) iscomplete, the

VxWorks kernel is initialized. The next phase of VxBusinitialization occurs in

sysHwInit2( ).

6、  phase 2, post-kernel initialization

sysHwInit2( )函数调用了vxbDevInit(),从驱动的角度理解,这是设备进一步初始化的窗口,在VxBus初始化阶段二,每个instance的devInstanceInit2()被调用,这时候内核服务就被初始化完成了。然而中间层服务还不能使用(such as network MUX),

By this point, kernel services are initialized and are accessible toyour driver.

7、  phase 3, asynchronous initialization

在sysHwInit2()结束时,创建了一个任务,这个任务运行第三方和VxBus驱动的最终的初始化工作,在第三阶段每个驱动的devInstanceConnect( )函数会被调用,这个阶段为哪些初始化时间比较长的驱动服务,这样就可以不会使系统启动时间变慢。devInstanceConnect()函数的执行可以同时在系统和应用配置和启动的时候发生。

 

通过代码查看实际的初始化过程是这样的(以vxbOmap35xxIntCtlr中断控制器为例):

 

 

 

void sysHwInit (void)-->

hardWareInterFaceInit ();-->

hardWareInterFaceBusInit();-->

vxbOmap35xxIntCtlrRegister();-->

vxbDevRegister(struct vxbDevRegInfo *)&omapIntCtlrDevRegistration);

vxbDevRegister()函数定定义在VxBus.c文件中

函数传入的参数为

LOCAL struct vxbDevRegInfo omapIntCtlrDevRegistration = {

    NULL,                           /* pNext */

    VXB_DEVID_DEVICE,               /* devID */

    VXB_BUSID_PLB,                  /* busID = PLB */

    VXB_VER_4_0_0,                  /* busVer */

    "vxbOmapIntCtrl",               /* drvName */

    &omapIntCtlrFuncs,              /* pDrvBusFuncs */

    NULL,                           /* pMethods */

    NULL,                           /* devProbe */

    NULL                            /* pParamDefaults */

};

分别对应

struct vxbDevRegInfo {

    struct vxbDevRegInfo * pNext; /* for next bus type */

    /* device or bus controller: BUS_DEVID_DEVICE or BUS_DEVID_BUSCTRL */

    UINT32  devID;

    UINT32  busID; /* bus type and bus subsystem version */

    UINT32  vxbVersion;

    char    drvName[MAX_DRV_NAME_LEN+1];    /* dev/drv name */

    struct drvBusFuncs * pDrvBusFuncs; /* default registration functions */

    struct vxbDeviceMethod * pMethods;

    BOOL (*devProbe) /* NULL probe routine indicates always true */

(

    struct vxbDev * pDevInfo    /* device info */

    );

    struct vxbParams * pParamDefaults;

    };

具体语句的解析:

VXB_ASSERT(pDevInfo!=NULL, ERROR);//断言

if ( vxbDrvVerCheck(pDevInfo) != OK )//判断版本信息,版本高于4则报错,兼容问题吧

        return(ERROR);

….

pCurrent = pDevInfo;

while ( pCurrent != pListEnd )  //遍历初始化

        {

        VXB_DEBUG_MSG(2,"vxbDevRegister() checking for orphans on %s\n",

                    (int)vxbBusTypeString(pCurrent->busID), 2,3,4,5,6);

 

        vxbDevIterate(vxbNewDriver, pCurrent, VXB_ITERATE_ORPHANS);

        pCurrent = pCurrent->pNext;

        }

vxbNewDriver (struct vxbDev * pDev,  void * pArg)也是定义VxBus.c文件中

他的第一个参数是设备信息,第二个参数是vxbDevIterate传过来的

主要是匹配设备信息,完成instance并将其插入到VxBus中,然后调用

vxbDevInitRun(pDev, pDriver);

LOCAL void vxbDevInitRun(VXB_DEVICE_ID devID,struct vxbDevRegInfo * pDrv)

该函数分三个阶段分别调用驱动相应的devInstanceInit、devInstanceInit2和devInstanceConnect函数,对设备进行初始化。

 

 

VxBus设备驱动编写步骤

 

设备驱动的组织:

(1)      驱动的组成目录:

 

installDir/vxworks-6.x/target/3rdparty //供应商或者用户编写的驱动

installDir/vxworks-6.x/target/src/hwif  //windriver公司提供的驱动

installDir/vxworks-6.x/target/src/drv  

 

 

 

(2)      所需的文件:

a driver source file—implements the runtime logic of the driver

driver source file是实现设备驱动的逻辑函数,一个设备驱动可以包含一个或者多个头文件,也可以包含多个源文件,具体的设备驱动架构参考《VxWorks设备驱动架构.docx》

 

a component description file (CDF)

关于CDF文件介绍及如何创建CDF参考《关于Component Description File.docx》

 

Driver Configuration Stub Files

对于一些BSP,VxWorks提供了两种不同的方式创建run_time镜像

(1)       使用workbench或者命令行创建image

(2)       将make命令直接放在BSP目录下。

第一种方法支持所有的BSP

第二种方法允许你通过将make命令加入到BSP目录下的方式创建image,在BSP是通过自己的Makefile创建的情况下,在驱动的CDF下的配置信息不会被用来配置BSP,因而,BSP作者需要直接在BSP源码目录下通过添加或者删除component,通过在BSP的config.h文件中指定添加或者删除哪些component。

例如:如果你想在run-time镜像中添加CN3xxx timer driver,你可以在config.h文件中添加一行:         #define DRV_TIMER_CN3XXX

注意:这种方法直接忽视了CN3xxx timer driver依赖其他component,如果CN3xxx timer driver也依赖别别的component,那么也需要在config.h中包含。

为了支持直接通过BSP创建driver,还必须添加两个配置文件

a driverName.dc file

a driverName.dr file

这两个文件链接设备驱动和BSP命令行。

依然使用Cn3xxx timer driver 作为例子,那么就有vxbCn3xxxTimer.dc文件:

IMPORT void vxbCn3xxxTimerDrvRegister();

这个文件的目的是为设备驱动注册提供函数原型。

vxbCn3xxxTimer.dc文件也有相似的描述:

#ifdef DRV_TIMER_CN3XXX

vxbCn3xxxTimerDrvRegister ();

#endif /* DRV_TIMER_CN3XXX */

这个文件的目的是调用驱动注册函数,这个函数必须要通过#ifdef/#endif包围以来保证注册函数只有在config.h中包含了才能执行。

         对于windriver驱动,.dr和.dc文件都放在target/config/comps/src/hwif

         对于第三方驱动,这两个文件放在相应的驱动源文件目录中。

为了使得这两个文件有效,必须将它们合并到初始化文件中,VxWorks的makefile环境包含所有创建这个初始化文件必须的命令,如果在VxWorks的源码树上添加了一个新的驱动,初始化文件必须按照如下重新创建。

在命令行输入:

% cd installDir/vxworks-6.x/target/config/comps/src/hwif

% make vxbUsrCmdLine.c

运行上述命令后,VxWorks的Makefile会搜索所有的驱动配置文件,最后将其整合到target/config/all/目录下的vxbUsrCmdLine.c文件中。

 

a  README file—provides versioning information

 

a makefile (Makefile)—provides the make rules used to build the driver

为了使得设备驱动能够在VxWorks下正确的被编译,必须提供一个相应的Makefile使得你的设备驱动能够被整合到可以被链接到VxWorks的镜像的目标文件中,需要两个Makefile:

1、设备供应商的Makefile  installDir/vxworks-6.x/target/3rdparty/vendor/

2、设备驱动的Makefile  installDir/vxworks-6.x/target/3rdparty/vendor/driver/

Makefile的内容可能比较复杂,可以拷贝相近的示例Makefile,然后修改

 

 

 

 

 

你可能感兴趣的:(VxWorks)