VxBus是风河公司新的设备驱动程序架构,是VxWorks新增的特性,它是在VxWorks6.2及以后版本被增加到VxWorks中的。
开发步骤
Vxworks中采模块化的方式管理各个功能单元,驱动也是由一个或多个模块组成。
VxBus是vxworks中的模块化机制。类似于linux中的module。通过vxBus我们可以方便的裁剪或添加新的模块。
模块的裁剪通常是在vxworks的开发环境workbench中进行的。建立一个工程后,会得到一个config文件,通过鼠标操作就可以实现模块的裁剪。
添加新模块则复杂一些,需要添加几个新的文件,但内容很简单,只是用来设置一些必须的信息。添加完成后,就可以像标准模块一样裁剪了。添加模块的详细过程可以再workbench中的vxbus的pdf文档中得到,说的很详细。
vxbus驱动的注册通过vxbDevRegister实现。其原型如下:
STATUS vxbDevRegister ( struct vxbDevRegInfo * pDevInfo /* per-bus recognition info */ )
显然,我们唯一要做的就是填充结构体pDevInfo,其类型定义如下:
BSP用于初始化硬件、引导操作系统并提供软件和硬件之间的设备驱动接口,针对某类体系结构的处理器开发BSP时,了解其基本的体系结构和指令系统是必要的。一般来说,BSP的设计与开发可分为几个步骤:
开发BSP过程中最主要的三个程序分别为:
下面根据代码详细分析vxWorks的启动顺序:
系统启动时,处理器首先会跳到ROM中的入口点_romInit()(位于romInit.s中),该处汇编代码如下:
_romInit: Cold: MOV r0, #BOOT_COLD warm: B start .ascii "Copyright …" .balign 4 start: /*此处添加延迟可以有效解决部分板件在复位后无法启动的问题*/ TEQ r0, #BOOT_COLD MOVEQ r1, #INTEGRATOR_DELAY_VALUE MOVNE r1, #1 delay_loop: SUBS r1, r1, #1 BNE delay_loop ... 此处即为vxWorks在ROM中的入口点,在此之前,sysLib.c中的函数sysToMonitor将检查指令的前三行,看他们是否发生改变,进而可判断是否为热启动,具体代码如下: if (p[0] == 0xE3A00002 && p[2] == 0x79706F43) pRom = (FUNCPTR)(ROM_TEXT_ADRS + 4); /* warm boot address */ else pRom = (FUNCPTR)ROM_TEXT_ADRS; /* start of ROM */ 由上面代码可知,对于热启动,处理器在执行函数romInit的同时会先增加一个小的偏移量, romInit中的代码的需要用汇编语言实现,主要用于分配内存,初始化处理器状态字以及创建临时堆栈,另外,它还会初始化尽量最少的必需硬件、屏蔽中断、清空cache。如果romInit函数执行正确,从LOCAL_MEM_LOCAL_ADRS到LOCAL_MEM_LOCAL_ADRS+ LOCAL_MEM_SIZE的内存空间都将是可读写的,否则,说明此函数执行失败。romInit执行成功后,会确定启动类型并作为参数跳转到bootInit.c中的C函数romStart()中,跳转代码如下: LDR r12, L$_rStrtInRom ORR r12, r12, #1 /* in Thumb case */ BX r12 而L$_rStrtInRom就是函数romStart的地址: L$_HiPosn: .long ROM_TEXT_ADRS + HiPosn - FUNC(romInit) L$_rStrtInRom: .long ROM_TEXT_ADRS + FUNC(romStart) - FUNC(romInit)
romInit传递的参数(即上面定义的BOOT_COLD)决定了在romStart中是否清空(内存冷启动)。
作者:Escorpion
VxBus是指在 VxWorks 中用于支持设备驱动的特有的架构,这种架构包含对minimal BSP的支持。它包括以下功能:
VxBus是Vxworks的模块化机制,类似于linux中的module。通过VxBus可以对模块方便的裁剪或者添加。VxBus 在总线控制器驱动程序服务的支持下,能在总线上发现设备,并执行一些初始化工作,使驱动与硬件设备之间正常的通讯。
vxBus下对设备管理做了更为详细的划分,简单说来,硬件称为device,软件叫做driver。如果一个device出现在硬件列表中,启动时需要到driver的队列中去找相应的driver,如果找到,二者结合成一个instance,否则在vxBusShow里可以看到一个orphan。使用vxBusShow可以比较清晰的看到driver列表和device列表以及orphan列表。
设备注册:vxbDevRegister(structure vxbDevRegInfo *pDevInfo)
显然,我们唯一要做的就是填充vxbDevRegIndo *pDevInfo结构体,其定义如下
struct vxbDevRegInfo { struct vxbDevRegInfo * pNext; UINT32 devID; UINT32 busID; UINT32 vxbVersion; char drvName[MAX_DRV_NAME_LEN+1]; struct drvBusFuncs * pDrvBusFuncs; struct vxbDeviceMethod * pMethods; BOOL (*devProbe) ( struct vxbDev * pDevInfo); struct vxbParams * pParamDefaults; };
Workbench3.0是VxWorks 6.x的集成开发环境,而VxWorks 5.5是采用Tornado2.2来进行开发的。Workbench3.0相比Tornado2.2来说提供了更为强大的功能,在Workbench3.0可以根据需要创建各种工程,常用的有以下几种VxWorks Image Projects,Boot Loader/BSP Projects,VxWorks Real-time Process Projects,VxWorks Downloadable Kernel ModuleProjects.
在进行驱动开发时需要创建VxWorks Image Projects。基于VxBus架构模型驱动在开发环境Workbench3.0中是以组件的形式体现的,这样的话就方便开发人员根据需要进行驱动的添加,重新编译VxWorks image后就可将驱动编进内核。开发人员只需将精力集中在驱动源码的编写上了。VxWorks5.5中没有VxBus架构,它的驱动的调用直接在BSP中的sysLIib.c中调用即可,这样开发的驱动可移植性不够好,当更换BSP时,又得重新移植。
关于Workbench3.0 的使用详见wr_workbench_vxworks_users_guide_3.0.pdf。
驱动源码结构
1 README
关于驱动的说明文件
2 Makefile
驱动的编译规则
3 driverName.cdf
驱动的描述文件,里边包括的该驱动依赖的组件,驱动的位置,父目录以及子目录,在Workbench3.0下的说明信息等,很重要,若不正确,在Workbench3.0无法添加。
4 driverName.dr
向VxBus进行注册的函数。
5 driverName.dc
向VxBus进行注册的函数的声明。
6 driverName.c
驱动的核心文件,驱动源码基本结构如下(用CAN1000t.c来举例)
VxWorks 6.x引入了新的vxbus的驱动架构,对于用惯了VxWorks 5.x的朋友来说,确实有点不习惯,本文简单介绍如何在vxworks系统下使用vxbus,希望对于初学vxbus架构的朋友有所帮助!
VxVorks中采模块化的方式管理各个功能单元,驱动也是由一个或多个模块组成。VxBus是vxworks中的模块化机制。类似于linux中的module。通过vxBus我们可以方便的裁剪或添加新的模块。
模块的裁剪通常是在vxworks的开发环境workbench中进行的。建立一个工程后,会得到一个config文件,通过鼠标操作就可以实现模块的裁剪。
添加新模块则复杂一些,需要添加几个新的文件,但内容很简单,只是用来设置一些必须的信息。添加完成后,就可以像标准模块一样裁剪了。添加模块的详细过程可以再workbench中的vxbus的pdf文档中得到,说的很详细。
vxbus驱动的注册通过vxbDevRegister实现。其原型如下:
STATUS vxbDevRegister ( struct vxbDevRegInfo * pDevInfo /* per-bus recognition info */ )
显然,我们唯一要做的就是填充结构体pDevInfo,其类型定义如下:
struct vxbDevRegInfo { struct vxbDevRegInfo * pNext; UINT32 devID; UINT32 busID; UINT32 vxbVersion; char drvName[MAX_DRV_NAME_LEN+1]; struct drvBusFuncs * pDrvBusFuncs; struct vxbDeviceMethod * pMethods; BOOL (*devProbe) ( struct vxbDev * pDevInfo); struct vxbParams * pParamDefaults; };
devProbe用于设备probe设备。检测当前是否有该类型设备。如果不需要进行probe,则可以设为NULL。
pNext用于总线级联。如一个挂在网卡上的网卡,其phy通过mii与mac相间接。我们要访问phy,则需要先通过pci总线访问mac,在通过mii总线访问phy。有点类似先做汽车到县城,再转驴车到村子。这里的pNext就是告诉你下面该转驴车了。如果没有级联,则设为NULL。 pMethods用于提供了总线的各种方法,但实际上通常只提供该总线特有方法。因为通用方法,如open、read等,一般都是通过io层的system call调用的,他们需要单独注册。
pDrvBusFuncs提供了设备初始化需要的几个接口,一共有三个:
© 2024 VxWorks Club