为您推荐:
精华内容
最热下载
问答
  • 82B dongjingjun 2008-11-04 12:27:58
  • 版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。 ... 8D Spaces Reliability & Stability & Efficiency 目录视图摘要视图订阅 VxWorks驱动程序开发指南(四)...

    版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
    本文链接:https://blog.csdn.net/yz2010/article/details/70198956
     
    8D Spaces
    Reliability & Stability & Efficiency
    目录视图摘要视图订阅
      VxWorks驱动程序开发指南(四)--驱动程序的组织结构
    2013-01-26 01:49 1696人阅读 评论(0) 收藏 举报
    本文章已收录于:   嵌入式开发知识库
     分类:vxbus vxworks(2) 
    版权声明:本文为博主原创文章,未经博主允许不得转载。

    目录(?)[+]

    驱动程序的组织结构

    驱动程序最重要的部分就是驱动程序源代码文件,源文件描述了设备如何和VxBus、VxWorks OS交互。但是,VxWorks 设备驱动程序还需要另外一些文件,这些附加文件能够帮助你将自己编写的驱动集成到VxWorks编译环境中去,这也是发布驱动程序最重要的一步。本节主要讨论如何在源码树中找到相关的驱动程序文件和其他附加文件。最后还说明驱动程序的各个部分是如何安装在VxWorks OS中的。

    3.1 文件位置
    在开发驱动程序之前,了解驱动程序文件在VxWorks源码树中的位置是非常重要的,驱动程序文件主要分布在源码树中的3个不同位置。

    installDir/vxworks-6.x/target/3rdparty      第三方提供的基于VxBus驱动模型的驱动,它们一般都做为插件安装到现有的VxWorks开发环境中
    installDir/vxworks-6.x/target/src/hwif       风河官方提供的基于VxBus驱动模型的驱动程序,它们一般都作为标准产品的一部分,或者作为补丁来升级。
    installDir/vxworks-6.x/target/src/drv         风河官方提供的基于传统模型的驱动程序,和VxBus不兼容
    3.3.1 风河官方的驱动程序
    根据驱动程序的类型,installDir/vxworks-6.x/target/src/hwif目录下的驱动被组织成不同的子目录,例如,定时器的驱动程序在目录installDir/vxworks-6.x/target/src/hwif/timer

    3.3.2 第三方的驱动程序
    第三方驱动程序的组织方式允许驱动程序开发厂商和开发者创建第三方驱动程序,不需要担心不同厂商的文件之间的命名空间冲突。每一个想提供VxWorks驱动程序的厂商必须在3rdparty目录创建自己的子目录,比如说,Acme公司计划为vxworks开发第三方设备驱动程序,那么就必须在3rdparty目录创建自己的目录installDir/vxworks-6.x/target/3rdparty/acme,在这个目录下,不同类型的驱动程序又组织成不同目录,跟hwif目录一样。

    3.2 驱动程序文件例子:wrsample
    风河公司提供的VxBus的驱动程序例子位于目录:installDir/vxworks-6.x/target/3rdparty/windriver/wrsample,这些文件可以被当做模板来帮助你开发第三方驱动程序,具体信息请参考wrsample目录下的README文件。

    3.3 其他必须的文件
    尽管一个驱动程序可以包括很多文件,比如多个源文件和多个头文件,但是一个标准的VxWorks驱动程序有一个最小的文件集,对于大多数vxworks驱动程序最少要求6个文件:

    驱动程序源文件                       实现驱动程序控制逻辑
    组件描述文件(CDF)          主要用于将驱动程序集成到VxWorks编译环境中,以便于配置
    一个driverName.dc文件        提供驱动注册例程的原型
    一个driverName.dr文件         提供一小段调用驱动注册例程的代码
    README文件                          提供版本信息
    Makefile文件                            提供编译规则
    一般情况下,CDF文件,dc文件,dr文件都被认为是驱动程序的配置文件,下面详细介绍这些文件。

    3.3.1 驱动程序源文件
    驱动程序源文件包含了驱动程序功能的实现逻辑,它们被放在目录installDir/vxworks-6.x/target/src/hwif, 第三方的被放在目录installDir/vxworks-6.x/target/3rdparty。很多VxWorks设备驱动程序只包含一个源文件,一个驱动程序可以包含一个或者几个可选的头文件;但是驱动程序可以包含多个源文件,但是此时必须在Makefile里面提供各个模块的依赖规则。下面以文件vxbCn3xxxTimer.c来说明VxWorks驱动程序的结构。

     

    设备驱动程序的第一部分是一个描述VxBus初始化阶段要调用的例程的结构:

    [cpp] view plain copy
    <span style="font-size:18px;">/* data structures used by the driver to register itself 
    * with Vxworks 
    */  
    /* drvBusFuncs provides a set of entry points into the 
    * driver that are called during various phases of the 
    * boot process. Drivers can choose to implement 1 or 
    * more of these entry point, according to the needs of 
    * the driver during its initialization phases. 
    */  
    </span><span style="font-size:18px;color:#ff0000;"><strong>LOCAL struct drvBusFuncs cn3xxxTimerDrvFuncs =  
    {  
    cn3xxxTimerInstInit, /* devInstanceInit */  
    cn3xxxTimerInstInit2, /* devInstanceInit2 */  
    cn3xxxTimerInstConnect /* devConnect */  
    };</strong></span>  
    接着就是描述驱动程序所支持的驱动方法的数据结构(每一种类别的驱动程序都必须实现该类的驱动方法):

    [cpp] view plain copy
    <span style="font-size:18px;">/* cn3xxxTimerDrv_methods provides the list of driver 
    * methods that this driver supports. For each driver 
    * class supported by Wind River, one or more methods 
    * are expected to be defined for the driver. For 
    * timer driver class, the 'vxbTimerFuncGet' method 
    * is required to be supported. 
    */  
    </span><span style="font-size:18px;color:#000000;">LOCAL struct vxbDeviceMethod cn3xxxTimerDrv_methods[] =  
    {  
    DEVMETHOD(vxbTimerFuncGet, cn3xxxTimerFuncGet),  
    {0,NULL}  
    };</span>  
    跟着就是描述该驱动程序需要的注册信息的结构:

    [cpp] view plain copy
    <span style="font-size:18px;">/* The cnxxxTimerDrvRegistration structure provides a 
    * description of the driver to VxWorks, so that VxWorks 
    * can connect this driver to appropriate hardware during 
    * the boot process. 
    */  
    </span><span style="font-size:18px;color:#000000;">LOCAL struct vxbDevRegInfo cn3xxxTimerDrvRegistration =  
    {  
    NULL, /* reserved for VxBus use */  
    VXB_DEVID_DEVICE, /* devID */  
    VXB_BUSID_PLB, /* busID = PLB */  
    VXB_VER_4_0_0, /* vxbVersion */  
    "cn3xxxTimerDev", /* drvName */  
    &cn3xxxTimerDrvFuncs, /* pDrvBusFuncs */  
    NULL /* pMethods */  
    NULL /* devProbe */  
    };</span>  
    在注册信息后面,驱动程序必须提供一个例程来向VxBus注册,表明该驱动程序的存在:

    [cpp] view plain copy
    <span style="font-size:18px;">/* The vxbCn3xxxTimerDrvRegister function contains the 
    * first instructions of the device driver that are 
    * ever executed within a VxWorks system. This function 
    * registers the driver with VxBus by providing pointers 
    * to the data structures listed previously. Once this 
    * step is complete, VxWorks is able to associate this 
    * driver with appropriate hardware within the system 
    * to form an instance. 
    */  
    </span><span style="font-size:18px;color:#000000;">void vxbCn3xxxTimerDrvRegister (void)  
    {  
    vxbDevRegister (&cn3xxxTimerDrvRegistration);  
    }</span>  
    由于驱动程序注册方法被当做是驱动程序的第一个入口点,VxWorks必须被配置成:当该驱动程序向VxBus注册时,VxWorks知道调用该入口点。为了做到这点,VxWorks使用了之前提到了那几个驱动配置文件:CDF文件,dc文件,dr文件。

    注意:VxBus和VxWorks要求驱动程序的注册方法必须是全局的。大多数驱动程序并不需要其他的全局符号,因此都可以声明成LOCAL。

    3.3.2 CDF文件
    该文件的全称是:component description File,组件描述文件。根据VxBus标准开发的VxWorks设备驱动程序都被编译成一个单独的模块,可以使用VxWorks配置工具非常轻松地将驱动程序配置进BSP中。但是,你必须为你的设备驱动程序创建一个VxWorks组件。

     

    一个组件是一个基本的功能单元,它可以单独配置进入VxWorks内核镜像中。为了能够单独添加和删除设备驱动程序到VxWorks中,驱动程序必须能够被VxWorks配置工具识别成individual 组件。为了让驱动程序能够在Workbench或者vxprj中是可以配置的,你必须创建CDF文件,CDF文件提供VxWorks配置工具所需要的信息。针对风河公司发布的设备驱动程序,其对应的CDF文件位于以下目录:

    installDir/vxworks-6.x/target/config/comps/vxWorks

    在风河提供的驱动程序中,一个CDF文件可能包含着描述多个设备驱动程序的信息,对于第三方驱动,其CDF文件路径是在驱动程序目录下。

    注意:内核配置工具并不自动搜索installDir/vxworks-6.x/target/3rdparty/ directories下的文件,为了让内核配置工具能够读取第三方驱动的CDF文件,必须手工将CDF文件拷贝到以下目录:installDir/vxworks-6.x/target/config/comps/vxWorks

     

    为新驱动编写CDF文件之前,首先拷贝一个标准的CDF文件到你的驱动程序目录,然后根据你的驱动程序来修改CDF文件。CDF文件主要放在以下目录:

    installDir/vxworks-6.x/target/config/comps/vxWorks

    以下以一个PCI总线控制器的CDF文件为例,这个文件的路径是:installDir/vxworks-6.x/target/config/comps/vxWorks/40m85xxPci.cdf:

    [cpp] view plain copy
    <span style="font-size:18px;">/* 40m85xxPci.cdf - Component configuration file */  
    Component DRV_PCIBUS_M85XX {  
    NAME M85xx PCI bus  
    SYNOPSIS M85xx PCI bus controller Driver  
    MODULES m85xxPci.o  
    SOURCE $(WIND_BASE)/target/src/hwif/busCtlr  
    _CHILDREN FOLDER_DRIVERS  
    _INIT_ORDER hardWareInterFaceBusInit  
    INIT_RTN m85xxPciRegister();  
    PROTOTYPE void m85xxPciRegister (void);  
    REQUIRES DRV_RESOURCE_M85XXCCSR \  
    INCLUDE_PARAM_SYS \  
    INCLUDE_PCI_BUS \  
    INCLUDE_PLB_BUS \  
    INCLUDE_VXBUS  
    INIT_AFTER INCLUDE_PCI_BUS  
    }</span>  
    Component DRV_PCIBUS_M85XX {

    CDF文件使用上述语句来定义一个组件ID。VxWorks中的每个组件必须用Component关键字来描述,驱动程序的ID一般以DRV_开始,并在ID中包含该驱动程序的描述性信息,每一类的驱动程序对组件ID都有着相同的命名习惯,比如DRV_PCIBUS_M85XX意味着它是一个PCI 总线控制器的组件。设备驱动程序组件标准的命名习惯应该是:DRV_CLASS_NAME,组件名字必须是唯一的,因此DRV_CLASS_NAME中的DRV和CLASS都有可能相同,这就要求NAME必须唯一才行。如果为第三方驱动写CDF文件,可以考虑把VENDOR和驱动程序名作为NAME的一部分。总之,保证DRV_CLASS_NAME唯一就可以。

    注意:以前老的驱动程序一般以INCLUDE_开头,不过新驱动都更改了这一用法,使用DRV_开头。

     

    NAME     M85xx    PCI   bus

    这是名字域,可读性较强,会在内核配置工具的名字栏显示该域定义的信息

    SYNOPSIS M85xx PCI bus controller Driver

    摘要域,主要是对该组件的简短介绍

    MODULES m85xxPci.o

    模块域,它列举了编译驱动程序生成的目标文件的名字。当一个驱动程序被包含在工程中时,VxWorks配置服务会分析模块域定义的目标文件中的内容,以决定是否会包含其他组件来把该驱动程序编译进VxWorks镜像。MODULES和REQUIES域一起,提供了把驱动程序编译进VxWorks内核所有需要的信息。

    _CHILDREN FOLDER_DRIVERS

    这个域用来帮助Workbench对相似的组件的显示进行管理,如下图:

    _INIT_ORDER hardWareInterFaceBusInit

    这个初始化顺序域描述的是:在VxWorks启动的过程中,应该在什么时候初始化本驱动程序,所有的总线驱动程序都必须在hardWareInterFaceBusInit中初始化,PCI总线也不例外。

    INIT_RTN m85xxPciRegister();

    定义设备驱动程序的初始化方法,因此,我们必须在这个域提供驱动程序注册方法。这个只是一个初级或者说最小的初始化,后续的初始化会等到VxWorks找到相关的硬件后就会将驱动程序和硬件绑定,形成了一个实例。

    PROTOTYPE void m85xxPciRegister (void);

    驱动注册方法的原型定义

    REQUIRES …

    该域描述了驱动程序能够在VxWorks中正常工作所必须有的组件。这个域是必须存在的,因为不是所有设备驱动程序的依赖性都能够通过检查驱动中的unresolved externals来决定的。为了支持该驱动程序,它和MODULES域一起决定哪些组件还需要被包含进来。

    INIT_AFTER INCLUDE_PCI_BUS

    这个INIT_AFTER和INIT_BEFORE被用于指明INIT_ORDER的依赖性,INIT_AFTER说明必须先初始化PCI总线,才能够初始化本驱动。INIT_BEFORE是在这之前必须要初始化本驱动。

    HDR_FILES $(WIND_BASE)/target/src/hwif/h/end/fei8255xVxbEnd.h

    上面的这行代码并没有在例子中出现,HDR_FILES主要提供驱动注册函数的原型

     

    CFG_PARAMS参数配置

    在初始化期间,有时候设备驱动程序需要一些配置信息,如果这些信息是和设备而不是实例相关的,则可以再编译阶段通过传递参数来实现。CFG_PARAMS和Parameter关键字将帮你实现这些任务。CFG_PARAMS用来指明组件要用的参数,而Parameter用来定义参数。如:

    [cpp] view plain copy
    <span style="font-size:18px;">Component DRV_NET_SAMPLE {  
    NAME network device supporting jumbo frames  
    ...  
    CFG_PARAMS SAMPLE_JUMBO_MTU_VALUE  
    }  
    Parameter SAMPLE_JUMBO_MTU_VALUE {  
    NAME Jumbo frame MTU size  
    SYNOPSIS max num of bytes in a jumbo MTU  
    TYPE int  
    DEFAULT 9000  
    }</span>  
    每个参数都必须有NAME,SYNOPSIS,TYPE,DEFAULT四个域。TYPE描述了参数的数据类型,包括任何C类型,BOOL,string(NULL-terminated);DEFAULT定义的值是参数的默认值。

     3.3.3 驱动程序配置文件
    对于某些BSP,VxWorks支持两种不同的方式来构建VxWorks镜像,一是使用Workbench或者vxprj命令行工具,二是直接在BSP目录中调用make命令。所有的BSP都支持第一种方法,尽管大多数都支持make方式,但是并不是所有的VxWorks开发环境和SMP都支持。

     

    当从makefile文件编译BSP时,CDF里面的信息并不用来配置BSP,程序员反而可以在BSP源文件config.h里面直接通过INCLUDE和EXCLUDE添加、删除某些组件,例如,如果你把Cn3xxx定时器驱动程序包含进你的VxWorks镜像中,可以在BSP中定义:#define DRV_TIMER_CN3XXX,为了简单起见,这里假设DRV_TIMER_CN3XXX不依赖于其他组件。修改完config.h文件后,你可以在BSP目录中直接调用make工具来编译BSP,编译BSP后,刚刚添加的定时器驱动程序已经可以被包含进VxWorks镜像了。

     

    为了支持驱动程序在BSP中直接编译,你必须创建两个附加文件,前面提过的DC和DR文件,这两个文件的作用就是把驱动程序和BSP命令行工具关联起来。dc文件的名字必须和驱动程序源文件的名字一样(后缀不一样嘛),以CN3XXX定时器驱动程序为例,vxbCn3xxxTimer.dc文件如下:

    IMPORT       void vxbCn3xxxTimerDrvRegister();

    DC文件主要是提供驱动程序注册方法的原型声明,或者以#ifdef../#endif来包含住:

    #ifdef DRV_TIMER_CN3XXX

    IMPORT   void vxbCn3xxxTimerDrvRegister();

    #endif

     

    DR文件就更加简洁了,描述了如何调用驱动程序注册方法,vxbCn3xxxTimer.dr文件如下:

    #ifdef DRV_TIMER_CN3XXX

    vxbCn3xxxTimerDrvRegister();

    #endif

    注册方法必须使用#ifdef/#endif结构来包含,作用是当系统不包含此组件时,就不需要注册。在#ifdef后面使用的宏必须和CDF中使用的宏一致。对于风河公司提供的设备驱动程序,DC和DR文件的位置在以下目录:

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

    对于第三方驱动,DR和DC文件在驱动程序的目录下。为了使这些文件起作用,它们必须被合并到VxWorks镜像的初始化文件中,当新的驱动被增加到VxWorks源码树时,可以使用以下命令来重新创建初始化文件:

     cd installDir/vxworks-6.x/target/config/comps/src/hwif
     make vxbUsrCmdLine.c

    当执行MAKE命令时,它会搜索所有的驱动程序配置文件,并一起合并到vxbUsrCmdLine.c文件中,该文件的目录在:

    installDir/vxworks-6.x/target/config/all/vxbUsrCmdLine.c

    注意:vxbUsrCmdLine.c文件在以下几种情况下是不会被更新的:vxbUsrCmdLine.c的修改时间比dc、dr文件和installDir/vxworks-6.x/target/config/comps/src/hwif目录中的文件的修改时间要更新,在这种情况下,把以前的vxbUsrCmdLine.c文件重命名,并重新执行MAKE命令即可。

    3.3.4 README 文件
    虽然MAKE环境并不要求有README文件,但是每个设备驱动程序都应该提供README文件给最终用户。第三方厂商可能会在README文件里面描述驱动版本信息、驱动程序的文件列表、已知的缺陷等信息。README文件包括三个数据段和三个行分隔符:

    使用一行文字来表明这是某某驱动程序的README文件,可能会包括支持的设备信息,如:
    README: VxWorks/VxBus driver for device device

    第一个数据段和第二个数据段的分隔符
    该数据段描述本驱动程序支持的设备列表、已经测试过的设备,也描述了驱动程序的VxWorks和VxBus版本信息,最后还包括组成本驱动的所有文件列表等。
    第二个数据段和第三个数据段的分隔符
    驱动程序版本信息列表,以及各个版本的变更信息
    注意:驱动程序版本信息包括两个部分(例如2.3),不能使用3部分的版本信息格式,README文件的一个例子目录在:

    installDir/vxworks-6.x/target/3rdparty/windriver/wrsample

    3.3.5 设备驱动程序Makefiles
    为了在VxWorks环境中正确编译设备驱动程序,你必须提供合适的Makefiles。有两种makefile来帮助你解决问题,第一种是厂商的makefile,目录位于:installDir/vxworks-6.x/target/3rdparty/vendor/Makefile,第二种是驱动程序的makefile,目录位于:installDir/vxworks-6.x/target/3rdparty/vendor/driver/Makefile。这些makefiles里面的内容有点复杂,因此可以在以下目录拷贝一个makefile模板,然后修改即可:

    installDir/vxworks-6.x/target/3rdparty/windriver
    installDir/vxworks-6.x/target/3rdparty/windriver/wrsample

    (1)厂商makeflie

    厂商的makefile是被同一个厂商目录下的所有驱动程序共享的,它使用通配符来确定哪些驱动程序被安装到了厂商目录下,并为每一个设备驱动程序调用make命令。从目录installDir/vxworks-6.x/target/3rdparty/windriver拷贝makefile模板,并添加到对应厂商目录下installDir/vxworks-6.x/target/3rdparty/vendor,你可以根据makefile模板做相应的修改。

    (2)驱动程序makefile

    在以下目录创建驱动程序makefile

    installDir/vxworks-6.x/target/3rdparty/vendor/driver

    这个makefile文件用于编译驱动程序子目录中的源文件,这个makefile也可以从以下目录拷贝并加以修改:installDir/vxworks-6.x/target/3rdparty/windriver/wrsample。但是,跟厂商makefile不一样的是,驱动程序makefile不使用通配符来寻找驱动程序源文件,相反,它包含一个要生产的目标文件列表,并说明如何从源文件中编译生成这些目标文件。wrsample中的makefile的comment能够帮助你根据驱动程序来修改makefile,不过通常情况下,主要是修改LIB_BASE_NAME(公司名字),和OBJ_COMMON(要生产的目标文件列表)。另外如果你只想为某一CPU平台编译驱动程序,可以使用该CPU平台的定义来代替OBJ_COMMON,如POWERPC平台(OBJ_PPC32)。
     ———————————————— 
    版权声明:本文为CSDN博主「yz2010」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/yz2010/article/details/70198956

    展开全文
    qq_41044736 2019-08-19 21:40:01
  • unsigned short 16bit unsigned long 32bit int 32bit

    unsigned short  16bit

    unsigned long  32bit

    int       32bit

    展开全文
    qingfengtsing 2011-11-26 09:40:47
  • 转载自:http://aabbc1122.blog.163.com/blog/static/57043257201441593144707/如有侵权,请联系我删除VxWorks为块设备(磁盘)的实时使用提供了两种本地文件系统:一种与MS-DOS文件系统相兼容,另一种与RT-11文件...
    转载自:http://aabbc1122.blog.163.com/blog/static/57043257201441593144707/
    如有侵权,请联系我删除


    VxWorks为块设备(磁盘)的实时使用提供了两种本地文件系统:一种与MS-DOS文件系统相兼容,另一种与RT-11文件系统相兼容。这些文件系统的支持库分别为dosFsLib和rt11FsLib。VxWorks还提供了一种简单的raw文件系统,这个文件系统把整个磁盘作为一个单独的大文件。这个文件系统的支持库是rawFsLib。

    VxWorks还为不使用标准文件或目录结构的磁带设备提供了一个文件系统。磁带卷被看作一个raw设备,整个卷就是一个大文件。这个文件系统的支持库是tapeFsLib。另外,VxWorks提供了一个文件系统支持库cdromFsLib,它允许应用程序从依照ISO9660标准文件系统格式化的CD-ROMs中读取数据。
    在VxWorks中,文件系统不受块设备种类型或它的驱动程序的约束。VxWorks块设备都使用一个标准接口,以便文件系统可以与设备驱动程序自由的混合。做为选择,你可以写自己的能被驱动程序以相同方式使用的文件系统,只要在文件系统、驱动程序和I/O系统间遵循同样的标准接口。VxWorks的I/O体系结构使得在一个VxWorks系统中可以有多样的文件系统,甚至其类型也可以不同。块设备界面在3.9.4块设备中讨论。

    1 与MS-DOS兼容的文件系统:dosFs
    使用dosFs文件系统格式化的磁盘与MS-DOS(直至6.2版本)磁盘是相兼容的。由两个文件系统初始化的硬盘之间在格式上有细微区别。然而,数据自身是兼容的,而且dosFs可被配置成使用MS-DOS格式化的磁盘。
    DosFs文件系统向不同要求的实时应用程序提供了良好的适应性。主要特点包括:
    l 文件和目录分等级排序,允许有效地组织,在一卷上可以创建任意数量的文件。
    l 每个文件可以是连续存储或非连续存储的。非连续存储的文件可使硬盘空间利用率更高,连续存储的文件可以增强系统性能。
    l 具有与广泛可用的存储器和可恢复介质的兼容性。应用VxWorks(不使用dosFs文件扩展名)、MS-DOS PCs和其它系统创建的磁盘可以自由的交换。如果分区表被说明,那么硬盘也是兼容的。
    l 具有从有dosFs文件系统的本地SCSI设备引导VxWorks的能力。
    l 可以使用比通常MS-DOS允许的8个字符的文件名加3个字符的扩展名更长的文件名。
    l NFS(网络文件系统)的支持。
    1.1磁盘组织
    MSDOS/ dosFs文件系统提供了一种以灵活方式组织磁盘数据的方法。它维护指定目录、每个包含文件或其它的目录的等级设置。文件可以被设置其搜索路径;文件扩展时,新的磁盘空间被自动分配。分配给一个文件的磁盘空间不必一定是连续的,这样可以使磁盘空间浪费最小。然而,为了提高它的实时性,dosFs文件系统允许连续空间被预先个别地分配给文件,从而使查找操作最块,行为更加确定。MS-DOS/dosFs文件系统的通常组织结构如图1,其中的多个单元在下面的部分论述。

    图1 MS-DOS磁盘组织
    -------------------------------
    引导扇区 扇区0
    -----------------------------
    文件分配表(FAT)
    -----------------------------
    根目录
    ------------------------
    文件和子目录
    ----------------------------


    在MS-DOS/dosFs文件系统中,分配给文件的磁盘空间由一个或多个磁盘簇组成。一个簇为一组连续的磁盘扇区 。软盘通常由两个扇区组成一簇;固定硬盘由更多的扇区组成一簇。文件系统可以一次分配的最小的磁盘空间为一簇。虽然每簇有巨大数量的扇区允许在固定大小的文件分配表( FAT;见 文件分配表)中描述一个巨大的磁盘,但是这可能会导致磁盘空间的浪费。
    引导扇区
    MS-DOS/dosFs硬盘或磁盘的第一个扇区称为引导扇区。其中包含有多种配置数据。其中一些数据域描述硬盘的物理性质(例如总扇区数),另外一些域描述文件系统变量(例如根目录的大小)。
    引导扇区信息在初始化时写入磁盘。dosFs文件系统可以使用在另一个系统上初始化过的磁盘(例如,在MS-DOS PC上使用FORMAT),或者VxWorks可以使用ioctl()调用中的FIODISKINIT函数初始化磁盘。
    随着MS-DOS标准的发展,多样的域被加入到引导扇区的定义中。VxWorks 下的磁盘初始化使用MS-DOS 5.0版本定义的引导扇区域。
    MS-DOS 初始化硬盘时,在引导扇区中加入一个分区表。而VxWorks不创建这样一个表。所以两个系统初始化的硬盘是不同的。如果设备的块补偿参数创建程序将超出分区表范围的数据指向数据区的第一个字节,那么VxWorks可以读取被 MS-DOS 格式化的磁盘文件。
    文件分配表
    每个MS-DOS/dosFs卷包含一个文件分配表(FAT)。对每一个分配给文件或目录的磁盘上的簇,FAT中都有一个条目。当簇没有使用过时(可分配),它的条目值为零。如果簇分配给一个文件,它的条目值是文件下一部分的簇号。如果簇位于文件的最后,它的条目值是-1。所以,文件或目录的表述由一个FAT条目链表组成。如2例所示,一个文件由簇2、300和500组成。簇3是没有使用过。

    注意:dosFs不映射坏的磁盘扇区到FAT中
    图2:FAT条目


    此主题相关图片如下:




    FAT的每个条目占12或16位。最多包含4085簇的磁盘卷用12位条目;多于4085簇的磁盘用16位条目。条目(特别是12位条目)最初利用英特尔8088体系配置的优点,编码为特殊形式。然而,因为所有的FAT操作都通过dosFs文件系统执行;所以编码和译码与 VxWorks应用程序无关。
    一个卷通常包括多个FAT拷贝。这种冗余允许数据在第一份FAT中发生介质错误事件时得到恢复。
    警告:如果是指定配置,dosFs 文件系统维护多个FAT拷贝;然而,在错误事件中,拷贝不是自动使用的。
    FAT的大小和FAT拷贝的数量是由引导扇区中的域决定的。对于使用dosFs文件系统初始化的磁盘,这些参数是在dosFsDevInit( )调用(通过设置卷配置结构DOS_VOL_CONFIG中域)期间被指定的。
    根目录
    每个MS-DOS/dosFs卷包含一个根目录。根目录总是占有紧接着FAT拷贝的一组连续的磁盘扇区。根目录占领的磁盘区域不在FAT中被条目描述。
    根目录的大小是固定的,它的大小被引导扇区中的一个域指定,作为允许的目录项的最大数值。对于使用dosFs文件系统初始化的磁盘,这个大小是在dosFsDevInit( )调用(通过设置卷配置结构DOS_VOL_CONFIG中域)期间被指定的。
    因为根目录有一个固定的大小,所以目录为满时再向其中加入项将返回一个错误。
    子目录
    除了根目录外,MS-DOS/dosFs卷有时包含一个子目录层。和根目录一样,子目录也包含文件和其它子目录项; 不过,在有些方面它们不同与根目录,而是类似于文件。
    l 第一、象文件一样,每个子目录都被另一个目录中的项描述。这样的一个目录项通过在文件属性字节中一个位设置来说明它描述了一个子目录。同时,子目录与根目录不同,它有用户指定名。
    l 第二、分配给子目录的磁盘空间由FAT条目连接而成的一组磁盘组成。这意味着子目录可以随着条目的加入而增大,并且子目录不一定要由连续的簇组成。根目录与子目录不同,能由任意数量的扇区组成,并且不必等于簇的整数倍数。
    l 第三,子目录通常包含两个专用的项。“.”项指向子目录本身,“..”项指向子目录的父目录。而根目录不包含这些专用项。
    文件
    在MO-DOS/dosFs文件系统中分配给文件的磁盘空间是由FAT中的条目链在一起的一组簇。一个文件不一定由连续的簇组成;可以以任意顺序分配磁盘任意位置的不同的簇。
    每个文件在其目录中有一个描述项。这个项包含文件名、大小、最后一次修改的时间和日期,还有文件的几个重要属性(只读文件,系统文件,隐藏文件,存档文件)。这个条目也包含文件的起始簇数;剩下的簇用FAT定位。
    卷标
    一个MS-DOS/dosFs磁盘可以有一个相关的卷标。卷标在根目录中是一个特殊项。它不包含文件名和子目录,而是包含一个识别卷的字符串。这个字符串可以包含最多11个字符。卷标项是通过在目录项中的一个特殊的文件属性字节的值来识别的。
    注意虽然卷标条目没有用ls()报告出来。不过它占了根目录固定数目的条目中的一个。
    卷标可以通过使用带有FIOLABELSET函数参数的ioctl()调用加入到dosFs卷。如果卷标不存在,就在卷的根目录加一个卷标项,否则,改变卷标字符串的值。这个卷标条目占据一个固定的根目录条目数;当根目录满时增加一个条目将导致一个错误。
    当前的卷标字符串可以通过调用带有FIOLABELGET函数参数的ioctl()来获得。如果没有卷标,这个调用将返回一个错误,并设置errno为S_dosFsLib_NO_LABEL。
    在VxWork或MS-DOS5.0(或更高版本)下初始化的磁盘,其引导扇区也包含卷标字符串。
    1.2 初始化dosFs文件系统
    注意在任何其它操作能被执行之前,dosFs文件系统库(dosFsLib)必须通过dosFsInit()调用进行初始化。这个程序带有一个参数――可以在同一时间打开的dosFs文件描述符的最大数。文件描述符的数目是在初始化时被分配,而且应用程序打开一个文件、目录或文件系统设备时,就使用了一个文件描述符。
    dosFsInit()程序在I/O系统驱动器表中也为文件系统创建了一个条目(用isoDrvInstall())。这个条目为dosFs文件操作指定条目指针,并且可以用于dosFs文件系统中所有的设备。分配给dosFs文件系统的驱动器数记录在全局变量dosFsDrvNum中。
    DosFsInit()通常在VxWorks系统启动之后被usrRoot()任务调用。使用这种初始化,在项目工具VxWorks view中选择INCLUDE_DOSFS,在Params属性标记中设置NUM_DOSFS_FILES为想打开文件的最大数。
    1.3 使用dosFs初始化设备
    dosFs文件系统初始化后,下一步是创建一个或更多的设备。设备通过设备驱动器的设备创建程序(xxDevCreate())来创建。驱动程序向块设备描述符结构(BLK_DEV)返回一个指针。BLK_DEV结构描述了设备的物理形式,同时也指定设备驱动程序提供给文件系统的程序。更多块设备的信息参见3.9.4块设备。
    设备刚创建之后,块设备没有与其相关联的名字和文件系统。为了初始化一个块设备用于dosFs文件系统,已经创建好的块设备必须与dosFs相关联,并指派一个名字。这由dosFsDevInit()完成。它的参数有:用来标识设备的名字、块设备描述符结构和卷配置结构DOS_VOL_CONFIG(见4.2.4卷结构)。例子:
    DOS_VOL_DESC *pVolDesc;
    DOS_VOL_CONFIG configStruct;
    pVolDesc = dosFsDevInit ("DEV1:", pBlkDev, &configStruct);
    dosFsDevInit()调用执行下列任务:
    l 为设备命名,把设备加入I/O系统设备表(用iosDevAdd())。
    l 为设备分配并初始化文件系统卷描述符
    l 返回指向卷描述符的一个指针。这个指针用来在一些文件系统调用时识别磁卷
    用dosFs初始化设备并不格式化磁盘,也不用MS_DOS结构(根目录,FAT,等等)初始化磁盘。可以在有数据存在于MS_DOS文件系统中的磁盘上使用dosFsDevInit()调用;可以使用ioctl()函数中FIODISKFORMAT和FIODISKINIT分别实现磁盘格式化和DOS磁盘初始化。
    DosFsMkfs()调用提供了一种简易的dosFs设备初始化的方法。如下
    l 提供了一组缺省的配置值。
    l 调用dosFsDevInit()。
    l 使用带有FIODISKINIT的ioctl()函数初始化磁盘。
    默认的dosFsMkfs()不能使任何dosFs-specific卷选项
    (DOS_OPT_CHANGENOWARN,DOS_OPT-AUTOSYNC,DOS_OPT-LONGNAMES,DOS_OPT_LOWERCASE,或DOS_OPT_EXPORT)可用。在调用dosFsMkfs()初始化磁盘之前使用dosFsMkfsOptionsSet(),可以使这些选项中的所有组合有效。有关默认配置值的更多信息,见dosFsMkfs()手册。

    1.4 卷配置
    卷的配置结构(DOS_VOL_CONFIG)在调用dosFsDevInit()时使用。这个结构包含多种描述磁盘上数据分布的dosFs文件系统变量。结构中的大多数域与引导扇区中的相符。表1列出在DOS_VOL_CONFIG结构中的域。
    表1:DOS_VOL_CONFIG域。

    域 描述

    dosvc_mediaByte 媒体描述符字节
    dosvc_secPerClust 每簇的扇区数
    dosvc_nResrvd 第一个FAT拷贝之前的保留扇区数,最小值为1(引导扇区)
    dosvc_nFats FAT拷贝数
    dosvc_secPerFat 每个FAT拷贝的扇区数
    dosvc_maxRootEnts 根目录中条目的最大值
    dosvc_nHidden 隐藏扇区数,通常为0
    dosvc_options VxWorks特殊文件系统选项
    dosvc_reserved 风河公司为将来使用保留

    调用dosFsConfigInit()是初始化DOS_VOL_CONFIG的简便方法。它把配置变量作为参数并装入结构。这对从Tornado shell中交互地初始化设备很有用(见Tornado 用户手册:shell)。DOS_VOL_CONFIG结构必须在dosFsConfigInit( )调用前被分配。
    DOS_VOL_CONFIG 域
    在表1中除了最后两个DOS_VOL_CONFIG域,都描述了标准MS_DOS的特征。
    域dosvc_options对于dosFs文件系统很特殊。这个域可能的选项见表2
    表2:dosFs卷选项

    选项 16进制值 描述

    DOS_OPT_CHANGENOWARN 0x1 磁盘可能在没有警告的情况下被改动.
    DOS_OPT_AUTOSYNC 0x2 I/O期间使磁盘同步
    DOS_OPT_LONGNAMES 0x4 使用不受8.3规格的限制的大小写敏感文件名
    DOS_OPT_EXPORT 0x8 允许使用NFS输出
    DOS_OPT_LOWERCASE 0x40 在磁盘上使用小写文件名


    前两个选项说明同步磁盘缓存块与物理设备的动作。剩下的选项用于扩展dosFs的性能。
    DOS_OPT_CHANGENOWARN
    如果磁盘没有被卸载就可被替换,或在状态就绪检查中发生变化,则设置这个选项。在这种情形中,有规则的检查磁盘来确定否发生改变。这将引起系统重大的开支;那么,我们推荐使用一种总是在移除前同步和卸载磁盘的机制,或至少声明状态就绪改变的机制。如果这样的机制适当,或磁盘是不可移动的,则不设置这个属性。自动同步模式在DOS_OPT_CHANGENOWARN被设置时自动允许(见下面有关DOS_OPT_AUTOSYNC的描述)。
    DOS_OPT_AUTOSYNC
    设置这个属性可确保磁盘缓存器中的目录和FAT数据被修改后尽快写入物理设备,而不仅仅是在文件关闭时被写入物理设备。数据尽可能存储到物理介质上,从而避免在系统紧急事件中丢失数据。因为使用自同步模式时将降低性能,所以 。
    然而,DOS_OPT_AUTOSYNC设置不能使dosFs在每个write()后自动向磁盘中写数据。这将意味着极大地降低了性能。如果你的应用程序要求dosFs在每个write()后自动向磁盘中写数据,每次调用write()后使用带有FIOFLUSH的ioctl()函数
    注不论什么时候设置DOS_OPT_CHANGENOWARN,自动同步模式都可以自动允许。
    DOS_OPT_LONGNAMES
    设置这个属性使系统允许使用大小写敏感文件名,文件名长度不受MS-DOS8.3版本的限制。
    DOS_OPT_EXPORT
    设置这个选项来初始化想使用NFS输出的文件系统。dosFs初始化生成附加的支持NFS协议所需的内存数据结构。这个选项对初始化文件系统(可以被输出的)是必不可少的,但它不真正输出文件系统。
    DOS_OPT_LOWERCASE
    设置这个选项来迫使dosFs创建的文件名使用小写字母字符。
    (除了DOS_OPT_LONGNAMES选项是激活的,通常文件名用大写字母字符)如果dosFs卷是通过基于PC的NFS的客户机装载的,则需要设置这个选项。如果DOS_OPT_LONGNAMES选项也被指定,则这个选项无效。
    计算配置值
    在DOS_VOL_CONFIG结构中,dosvc_secPerClust和dosvc_secPerFat的值必须基于被使用的特殊的设备进行计算。
    dosvc_secPerClust
    这个域用来说明组成一个单独的簇的连续扇区数。因为一簇是每次可以被分配的最小磁盘空间,簇的大小决定了磁盘分配控制的细微程度。每簇中扇区数越多,每次分配的扇区数越多,从而降低了磁盘空间使用的整个效率。因此,通常每簇使用尽可能少的扇区,不过每簇少于两个扇区通常是不必要的。
    FAT条目最大为16位;那么,可以被描述的簇的最大值为65536(64KB,或0x1000),这就是一个设备的簇的最大值。为了确定一簇中适当的扇区数,以0x1000(64k)划分磁盘上的所有扇区(BLK_DEV结构中的bd_nBlocks域),进位舍入到下一个整数,最终结果就是每簇中的扇区数;把这个值赋予DOS_VOL_CONFIG结构中的dosvc_secPerClust域。
    dosvc_secPerFat
    这个域指定磁盘上每个FAT拷贝必需的扇区数。要计算出这个值,首先确定磁盘的总簇数。总簇数等于总扇区数(BLK_DEV结构中的bd_nBlocks)除以每簇的扇区数。如前面提到的,磁盘的簇的最大数为64KB。
    簇数随每个FAT条目的位数增加:如果总簇数小于等于4085,FAT条目为12位;如果簇数大于4085,FAT条目为16位。增加的结果是每个FAT拷贝所需的总字节数。这个字节数除以每个扇区的大小(BLK_DEV结构中的bd_bytesPerBlk域),决定了每个FAT拷贝的扇区数(按扇区的大小划分);如果有一些残余,结果再加一。把最终的值赋予dosvc_secPerFat域。
    假定512字节扇区,每个拷贝最大可能的FAT占用256个扇区,计算如下

    标准磁盘配置
    对于软盘,许多标准磁盘配置用于MS-DOS系统。通常,配置通过媒体描述符字节的值唯一识别(至少针对一种给定大小的软盘),虽然一些制造商对不同的格式使用完全相同的值。一些广泛使用的配置参见表3。
    固定磁盘不使用标准磁盘配置,因为它们很少附属于外部的系统,。通常固定磁盘使用0xF8的介质格式字节。
    表3:MS_DOS 软盘配置

    容量 160KB 180KB 320KB 360KB 1.2MB 720KB 1.44MB
    尺寸 5.25" 5.25" 5.25" 5.25" 5.25" 3.5" 3.5"
    面 1 1 2 2 2 2 2
    磁道 40 40 40 40 80 80 80
    扇区/磁道 8 9 8 9 15 9 18
    字节/扇区 512 512 512 512 512 512 512
    secPerClust 1 1 2 2 1 2 1
    nResrvd 1 1 1 1 1 1 1
    NFats 2 2 2 2 2 2 2
    如前所述,在dosfs文件系统设备应用dosfsdevinit()首次初始化时,多种磁盘配置参数被指定。这些参数保存在卷描述符dos_vol_desc中。而带有不同参数值的磁盘可能被放置在初始化过的设备驱动器中。如果用另一个磁盘取代磁盘(带有最后输入到卷描述符的配置参数),那么新磁盘的配置参数必须在使用之前获得。
    当磁盘被装载时,引导扇区信息从磁盘上读取出来。此数据用来更新在卷描述符中的配置数据。注意这个操作发生在磁盘存取的开始。而且在卷被卸载(使用dosfsvolunmount())或一个准备好的替换操作被执行之后,又再次执行这个操作。
    配置数据的自动重新初始化有重要的含义。卷描述符数据在初始化磁盘(使用fiodiskinit)时使用;这样,磁盘使用最近装载的磁盘的配置初始化,而不考虑在dosfdevinit()期间的初始规格,因此我们推荐在磁盘装载之前,在dosfsdevinit()之后紧接着使用fiodiskinit。(设备以raw模式打开,fiodiskinit ioctl()函数执行后,关闭设备。)

    已初始化过磁盘的使用
    如果你使用一块已经初始化过的有ms-dos引导扇区、fat、根目录的磁盘(例如,使用统一的ms-dos格式),则不需要在dosfsdevinit()中提供卷配置数据。
    可以忽略ms-dos配置数据(通过指定一个null指针代替在dosfsdevinit( )期间dos_vol_config结构的地址),不过仅仅在你确信卷的首次使用伴随完全格式化和初始化过的磁盘时才使用这种方法。
    当装载一个已经初始化过的磁盘时,所有标准的ms-dos配置值都从磁盘引导扇区获取。而指向dosfs的选项必须被指明。 。
    dos_opt_longnames(不受8.3版本限制的大小写敏感文件名),使用这个选项初始化过的磁盘可以通过引导扇区中一个特殊的卷id字符串自动识别。
    dos_opt_changenowarn, dos_opt_autosync, dos_opt_lowercase, 和 dos_opt_export选项只记录在内存中,不放在磁盘上。因此当用null代替dos_vol_config结构指针初始化磁盘时,不能删除这些选项。另外可以使用dosfsdevinitoptionsset()程序设置这些选项为默认值;除非支持明了的dos_vol_config信息,不然默认值将应用于后面所有使用dosfsdevinit()初始化的dosfs文件系统。

    卷配置信息访问
    可以通过在tornado shell中使用dosfsconfigshow()2和dosfsconfigget()获得磁盘信息。这里参考tornado(shell)。
    使用dosfsconfigshow()显示象最大连续区域和设备名这样的配置信息。例如:
    -> dosfsconfigshow "/ram1/"
    value = 0 = 0x0
    输出到标准输出设备,如下
    device name: /ram1/
    total number of sectors: 400
    bytes per sector: 512
    media byte: 0xf0
    # of sectors per cluster: 2
    # of reserved sectors: 1
    # of fat tables: 2
    # of sectors per fat: 1
    max # of root dir entries: 112
    # of hidden sectors: 0
    removable medium: false
    disk change w/out warning: not enabled
    auto-sync mode: not enabled
    long file names: not enabled
    exportable file system: not enabled
    volume mode: o_rdwr (read/write)
    available space: 199680 bytes
    max avail. contig space: 199680 bytes
    dosfsconfigget程序把磁盘信息存储到dos_vol_config结构中。这对于初始化一个新磁盘(与已有磁盘相同配置)很有用,另外对于用dosfsmkfs()在磁盘上初始化dosfs文件系统,并需要获取被计算的目前配置值也很有用。

    装载卷
    通常磁盘卷在对磁盘上文件或目录的第一个open()或creat()操作时自动装载。(某些ioctl()调用也可以引起磁盘装载)。 如果在dosfsdevinit()调用期间,一个null指针被指定代替dos_vol_config结构的地址,那么磁盘被立即装载以获得配置值。
    磁盘装载时,从磁盘上读取引导扇区、fat和目录数据。卷描述符dos_vol_desc被更新以反映新装载磁盘的配置。
    自动装载发生在dosfsvolumount()或替换就绪操作之后的第一个文件存取时。如果磁盘在带有dos_opt_changenowarn选项设置的dosfsdevinit()调用期间被定义,磁盘会被周期性地自动装载。当磁盘以raw模式打开时自动装载不会发生;见

    打开整个设备(raw模式)。
    警告:因为设备名是被使用简单子链匹配的i/o系统识别的,所以文件系统不使用单独的斜杠(/)作为文件名。如果使用斜杠可能发生意外的结果。
    可以使用usrfdconfig()装载卷,但是这个程序不返回dos_vol_desc结构。用usrfdconfig()装载的卷不能使用许多dosfs命令,包括dosfsvolunmount()。不过dofs的ioctl()命令(包括fiounmount)通过fd存取卷信息,所以可以和usrfdconfig()一起使用。

    文件i/o
    dosfs文件系统设备上的文件创建、删除、读写都使用标准vxworks i/o程序: creat( )、 remove( )、 write( )和read( )。


    整个设备的打开(raw模式)
    可以打开整个的dosfs卷。这是在open()和creat()调用期间通过只指定设备名来实现。当一个合法文件被打开时返回一个文件描述符;然而,在文件操作符上的操作影响整个设备。以这种方式打开整个卷叫作raw模式。
    打开整个设备的通常原因是为ioctl()函数获得一个不属于某个文件的文件描述符。如fionfree函数,它返回在卷上的有效字节数。然而,对于许多此类函数,文件描述符可以是任何打开的此卷的,甚至一个特定文件的文件描述符。
    当一个磁盘用ms-dos数据结构初始化(引导扇区、空的根目录、fat)时,以raw模式打开此设备。ioctl()函数fiodiskinit执行初始化。
    可以以raw模式读写磁盘上的数据。在这种模式下,整个的磁盘数据区被看作一个单独的大文件。没有目录条目用来描述用raw模式写的任何数据。
    有关对整个设备(包括使用ms-dos的数据结构的区域)低级i/o,,见4.4 raw文件系统:rawfs和有关“vxworks 参考手册>库”下的rawfslib的在线参考。

    子目录创建
    当子目录达到最大条目数时,子目录可以在根目录以外的任何目录下创建。子目录有两种创建方式:
    1. 使用带有fiomkdir函数的ioctl():目录名传递给ioctl()。ioctl()调用使用的文件描述符可以通过以下方式获得:打开整个卷(raw模式)、一个正规文件或卷上的另一个目录。
    2. 使用open():创建一个目录,o_creat选项必须设置在标记参量中打开,fstat_dir选项必须设置在模式参量中。open()调用返回一个文件描述符(描述新目录)。这个文件描述符用于只读,当不再需要时关闭这个描述符。
    使用以上两种方法的任意一种方法创建目录,新目录名必须被指明。这个名字可以是一个全称路径名,或是一个相对于当前工作目录的路径名。

    子目录删除
    被删除的目录必须是空的(除了“.”和“..”条目)。删除目录有两种方法:
    1. 使用带有fiormdir函数的ioctl()调用,指定目录名。另外,文件描述符可以指向卷上的任何文件、目录、或卷自己。
    2. 使用remove()函数,指定目录名。

    目录条目
    每个dosfs目录包含一组条目描述它的文件和子目录。每个条目包含有关文件或子目录的信息:
    文件名
    一个8字节字符串(如果需要,空格填补)指定文件名。(命名可以长至40个字符;详情见4.2.18长文件名支持)
    文件扩展名
    一个3字节的字符串(空格填补)指定文件名或子目录名的一个延长部分。(如果选择了不受8.3版本限制的高级文件名,扩展概念是不适用的。)
    文件属性
    一个字节域指定文件的特征;
    时间
    文件编码创建修改的时间
    日期
    文件编码的创建修改的日期
    簇号
    文件内开始簇的数目。通过搜索fat找后来的簇
    文件大小
    文件的大小,对描述子目录的条目来说这个域通常为零。

    读目录条目
    在dosfs卷上的目录可以使用opendir(),readdir(),rewinddir(),和closedir()程序来搜索。这些调用可以用来确定文件名和子目录。
    使用fstat()或stat()函数可以获得有关指定文件更详细的信息。连同标准文件信息,被这些程序使用的结构还从目录条目返回文件属性字节。


    文件属性
    在dosfs目录条目中的文件属性字节由一组标记位组成,每位标志一个特殊的文件特征。文件属性字节描述的特征见下表。
    表:文件属性字节中的标记

    vxworks 标记名 十六进制值 描述

    dos_attr_rdonly 0x01 只读
    dos_attr_hidden 0x02 隐藏文件
    dos_attr_system 0x04 系统文件
    dos_attr_vol_label 0x08 卷标
    dos_attr_directory 0x10 子目录
    dos_attr_archive 0x20 存档文件


    当一个文件被打开为o_wronly或o_rdwr时,dos_attr_rdonly被选中。如果标记设置了,open()返回error,并且设置errnos为_dosfslib_read_only。
    警告:ms-dos隐藏文件和系统文件标记(dos_attr_hidden和dos_attr_system)被dosfslib忽略。虽然他们保持完整,但他们不产生特殊的处理(例如,带有这些标记的条目当搜索目录时被公布)。

    卷标标记dos_attr_vol_label用来说明一个包含磁盘的dosfs卷标的目录条目。标签不是必须的,如果使用了,每卷只有一个卷标条目,在根目录中。当读一个目录的内容时,卷标条目不被报告(用readdir())。只有使用ioctl()函数fiolabelget时,卷标条目才被确定。使用ioctl()函数fiolabelset,卷标可以被设置成任何11个字符或更少字符的字符串。在这些ioctl()调用期间任何打开到此卷的文件描述符都可以使用。
    目录标记dos_attr_directory用来指出这个条目不是一个正规的文件而是一个子目录。
    存档标记dos_attr_archive在文件被创建或修改时被设置。这个标记被其他搜索卷的程序(寻找修改过的文件并选择存档)使用。这样的程序必须清除存档标记,因为vxworks不做这个工作 。
    属性字节中的所有标记(除了目录和卷标标记)可以使用ioctl()函数filoattribset设置或清除。这个函数调用在指定文件打开后改变其属性。在filattribset调用中指定的属性字节值被直接复制;为了保护存在的标记设置,使用stat()或fstat()确定当前的属性,然后使用and和or操作改变他们。
    例:设置dosfs文件属性
    这个例子使一个dosfs文件只读,并保持其他属性不变
    #include "vxworks.h"
    #include "iolib.h"
    #include "dosfslib.h"
    #include "sys/stat.h"
    #include "fcntl.h"
    status changeattributes (void)
    {
    int fd;
    struct stat statstruct;
    /* open file */
    if ((fd = open ("file", o_rdonly, 0)) == error)
    return (error);
    /* get directory entry data */
    if (fstat (fd, &statstruct) == error)
    return (error);
    /* set read-only flag on file */
    if (ioctl (fd, fioattribset, (statstruct.st_attrib | dos_attr_rdonly))
    == error)
    return (error);
    /* close file */
    close (fd);
    }


    文件日期和时间
    目录条目包含一个文件和目录的时间和日期。这个时间在文件创建时被设置,并在文件被修改后关闭时被更新。描述子目录的条目不被更新——它们总是包含目录的创建日期和时间。
    dosfslib库在内在结构中维持日期和时间。然而通常没有一个装置来自动更新时间和日期,这提供了两种不同的设置日期和时间的方法。
    第一种方法应用两个程序dosfsdateset()和dosfstimeset()。使用如下:

    dosfsdateset(1990,12,25)/*设置日期为1990年12月25日*/
    dosfstimeset(14,30,22)/*设置时间为14:30:22*/

    必须按时调用这些程序来更新日期和时间的值。
    第二种方法要求一个用户支持的钩子程序。如果使用dosfsdatetimeinstall()安装了时间和日期的钩子程序,只要dosfslib要求获取当前日期和时间,程序就被调用。这样可以利用可被读取硬件日历时钟来获取当前时间。也可以用于其它的维持当前时间日期的应用软件。
    定义日期/时间钩子程序如下(datetimehook是一个例子名,真正的程序名可以是任何名)
    void datetimehook
    (
    dos_date_time * pdatetime /* ptr to dosfs date & time struct */
    )
    在钩子程序的入口,包含最近的时间和日期的dos_date_time结构设置在dosfslib中。接下来,钩子程序用当前正确的时间和日期填充结构。结构中没有发生改变的区域保持先前的值。
    ms-dos规格在文件时间标记上仅提供了2秒间隔的时间戳。如果在dosfstimeset()或日期/时间钩子程序里指定的秒数是带零头的,那么它四舍五入到下一个偶数。
    dosfslib使用的日期和时间被初始为1998年1月1日,00:00:
    展开全文
    sfx90 2018-05-16 11:15:20
  • VxWorks支持多种文件系统,比較重要的有:1、dosFs:适用于块存取设备(比方硬盘、软盘)。和MS-DOS文件系统兼容;2、rawFs:提供了一种简单的原始文件系统。该文件系统将整个硬盘当作一个单独的大文件;3、cdromFs:...

      文件系统,是指操作系统依据文件夹和文件的组织形式在磁盘设备上应用的一种设备驱动,不同的文件系统对文件夹和文件有不同的限制(如文件夹名限制,文件限制大小等)。

    VxWorks支持多种文件系统,比較重要的有:

    1、dosFs:适用于块存取设备(比方硬盘、软盘)。和MS-DOS文件系统兼容;

    2、rawFs:提供了一种简单的原始文件系统。该文件系统将整个硬盘当作一个单独的大文件;

    3、cdromFs:同意系统从依照ISO9660标准文件系统格式化的CD-ROM上读取设备;

        通常文件系统驱动位于磁盘(块存取)设备驱动和IO系统之间,这一点在VxWorks中也不例外,但它在此基础上扩充了功能,即在文件系统下方添加了一个CBIO(Core Blocked IO)接口,在CBIO下方才是块存取设备驱动,其示意图例如以下:
     


    图1 VxWorks I/O系统层次图

    而CBIO接口部分又细分为4个逻辑子层,每一个逻辑层都有与创建文件系统相关的函数,将CBIO接口部分细分后。包括各子层相关操作函数的VxWorks文件系统示意图例如以下:

    图2 CBIO层内部结构层次图

    图中线框中的四层就是CBIO接口层里的子层。对内核配置了dosFs支持的VxWorks来说,对磁盘的管理是从BLK_DEV API设备驱动子层上開始的,不同子层上的函数创建出的CBIO句柄分属不同的层,下层的CBIO句柄即为上层CBIO句柄的附属CBIO句柄。也就是说它们尽管都是CBIO_DEV_ID类型,但依据产生它们的函数所在的层把它们按等级划分,一个CBIO缓冲区能够在每一个子层上都有一个CBIO句柄,也能够在部分子层上有CBIO句柄。CBIO缓冲区在基本CBIO to BLK_DEV设备子层上就没有句柄。图右側函数间的箭头指示了各子层间句柄的关系。此外,从图中能够看出,头文件也是依据层的划分来组织的。这样使得函数调用层次清晰。

     

    在磁盘上建立dosFs文件系统

    以运行在摩托罗拉公司的PPC860 CPU上的VxWorks为例,在配置VxWorks内核时加入IDE/ATA磁盘设备驱动,在系统启动后,系统就和磁盘相连,系统启动后会发现磁盘(运行指令:devs,列出的设备中有一个/ata0a),此时该设备尚无法訪问(就像刚出厂的硬盘用启动盘引导后能发现却不能使用一样。在dos下须要用fdisk工区来创建分区,格式化后才干使用),而在VxWorks下,系统也提供了相似的操作(如图2)。

    在创建文件系统之前,应通过在内核中包括dosFs组件来初始化dosFs文件系统,即让系统载入文件系统驱动。同意系统在块设备上创建文件系统设备。

    至此,系统启动后。用户直接面向的已经是BLK_DEVAPI设备驱动子层了。全部的操作都是从该层上方開始的。

    为了在磁盘上上创建分区、格式化并使用它,应进行以下操作:

    2.1创建块存取设备:

    对于磁盘设备,使用ataDevCreate()函数在BLK_DEV API设备驱动子层上创建一个指向块存取设备的指针pAta:

    BLK_DEV * ataDevCreate(int ctrl,intdrive,int nBlocks,int blkOffset)

     

    參数1表示磁盘设备控制器号。0表示primary,

    參数2表示磁盘设备驱动器号,0表示master。

    參数3表示驱动器设备上的块数量,0表示使用整个磁盘,

     

    參数4表示从驱动器開始处偏移的块数量。0表示从头開始。

    函数为指定的ATA/IDE磁盘或ATAPI CDROM创建一个设备。返回一个指向块设备结构(BLK_DEV)的指针。图2中在此处用pAta=ataDevCreate(0,0,0,0)创建一个指向块设备的指针pAta。该设备相应磁盘primary master,而且使用整个磁盘的从头開始的全部块。(不要混淆设备和磁盘。能够把磁盘的一部分创建为一个设备。即一个设备相应于一个磁盘和该磁盘里的块,而磁盘由控制器号和驱动器号唯一指定)

    2.2 创建磁盘快速缓冲区:

    该步骤是可选的。

    通过调用dcacheDevCreate()函数为一个块设备创建磁盘快速缓冲区并在CBIO to CBIO设备(dcacheCbio)子层上生成CBIO句柄。使用方法例如以下:

         CBIO_DEV_ID dcacheDevCreate(CBIO_DEV_ID subDev,char *pRamAddr,int memSize,char*pDesc)

     

    參数1表示一个CBIO句柄。该句柄作为返回的CBIO to CBIO设备(dcacheCbio)子层的CBIO句柄的附属CBIO句柄,该附属句柄由函数CBIO_DEV_ID cbioWrapBlkDev(BLK_DEV *)在基本CBIO to BLK_DEV设备(cbioLib)子层上生成。也能够使用块设备,当使用块设备时,实际上是将块设备转换成在基本CBIO to BLK_DEV设备(cbioLib)子层上的CBIO句柄后作为參数的;

     

    參数2表示该CBIO快速缓冲区在内存中的位置。

     

    參数3表示为该CBIO快速缓冲区使用多少内存;

    參数4表示设备描写叙述字符串。

    函数创建一个CBIO层磁盘快速缓冲区实例,并在CBIO to CBIO设备(dcacheCbio)子层生成CBIO句柄,当參数2为NULL时,參数3使用全部内存缓冲磁盘数据。当參数2为0时,參数3使用一个默认内存大小缓冲磁盘数据。參数4为设备描写叙述字符串。会在dcacheShow运行时作为结果的一部分输出。

    当须要多个快速缓冲区时非常须要(支持16个快速缓冲区)。

    当内存容量小于指定缓冲区大小时创建失败。

    图2中此处用cbio=dcacheDevCreate(pAta,0,0,“cache1”)为块设备pAta创建默认大小的快速缓冲区cbio,同一时候cbio也是该缓冲区在CBIOto CBIO设备(dcacheCbio)子层上的CBIO句柄。

    这里用块设备作为參数1比較直观。并描写叙述为“cache1”。也能够先使用bcbio=cbioWrapBlkDev(pAta),再使用cbio=dcacheDevCreate(bcbio,0,0,“cache1”),此时bcbio为cbio的附属句柄。

    2.3 创建和安装磁盘分区:

    通过调用usrFdiskPartCreate()在磁盘上创建分区表。然后通过调用dpartDevCreate()初始化一个分区的磁盘。并在CBIO to CBIO设备(dpartCbio)子层上创建CBIO句柄。例如以下:

    STATUSusrFdiskPartCreate(CBIO_DEV_ID cDev,int nPart,int size1,int size2,int size3)

    參数1表示一个CBIO句柄,分区表将在这个代表整个磁盘的句柄相应的块设备上创建,注意这里不是subDev,而是cDev,表示不要用附属CBIO句柄bcbio,而应使用cbio;

    參数2表示要创建的分区数,默觉得1。最大为4;

    參数3表示第2个分区所占用的空间百分比。

    參数4表示第3个分区所占用的空间百分比;

    參数5表示第4个分区所占用的空间百分比。

    该程序用来创建基本分区表,即对磁盘分区,仅仅能用来创建一个主分区表。即MBR,不能用于创建启动或扩展分区。返回一个指示操作成功与否的状态值。

    这时磁盘仅仅有分区表,还没有安装分区,能够用usrFdiskPartShow()显示创建的分区。

     

    图2中此处用usrFdiskPartCreate(cbio,2,50,0,0)在cbio相应的块设备上创建两个分区。各占磁盘一半空间。

    创建磁盘分区的操作函数dpartDevCreate()使用方法例如以下:

    CBIO_DEV_ID dpartDevCreate(CBIO_DEV_IDsubDev,int nPart,FUNCPTR pPartDecodeFunc)

     

    參数1表示一个附属CBIO句柄,即存在于以下子层上的cbio。

     

    參数2表示分区数量,

    參数3表示能解释分区表的函数。

    为了处理一个已分区的磁盘,即在磁盘上安装分区,须要使用该函数。推荐为了操作的高效,为整个磁盘创建一个快速缓冲区并在各分区间共享该快速缓冲区。nPart參数表示特定磁盘驱动器上最大的分区数,可支持最多24个。

    分区表解释程序:应该实现的功能是将已分区设备的分区信息解释成特定格式的结果。并将结果写入一个特定类型的表中。

    图2中此处通过调用cbio1=dpartDevCreate(cbio,2,usrFdiskPartRead)通过让usrFdiskPartRead程序解释cbio相应块设备的分区表来初始化分区的磁盘。usrFdiskPartRead程序是系统提供的解释分区表信息的程序,可直接调用。至此分区操作完毕。在创建文件系统和格式化分区后就可以使用分区了。注意程序返回的cbio1尽管和cbio类型同样,注意生成的句柄cbio1位于CBIO to CBIO设备(dpartCbio)子层上。

    2.4 创建dosFs文件系统:

    文件系统在VxWorks中也被看作一个设备。通过调用函数dosFsDevCreate()来在指定分区上创建dosFs文件系统。dosFsDevCreate()函数使用方法为:

    STATUS dosFsDevCreate(char*pDevName,CBIO_DEV_ID cbio,u_int maxFiles,u_int autoChkLevel)

     

    參数1表示创建文件系统后,相应分区的卷名,格式为“/卷名”;

     

    參数2表示特定分区的CBIO句柄,对本例,即用dpartPartGet(cbio1,0)或dpartPartGet(cbio1,1)返回的句柄,dpartPartGet要求使用位于CBIO to CBIO设备(dpartCbio)子层上的CBIO句柄,并把它定义为dosFs卷。

    參数3表示在设备上能同一时候打开的文件数。

    參数4表示是否在挂载卷时自己主动进行卷的完整性检測。

    该函数在一个特定CBIO句柄相应的分区上创建dosFs文件系统,定义每一个磁盘卷的信息并将它们加入到I/O系统中。

    图中此处用dosFsDevCreate(“/DOSA”,dpartPartGet(cbio1,

    0),16,0)在第一个分区(dpartParGet中的參数0)安装文件系统,卷名为/DOSA。并在挂载时自己主动进行完整性检測。

    2.5 格式化磁盘卷

        使用dosFsVolFormat()函数将磁盘卷按dos格式格式化。该步骤仅仅能在磁盘卷第一次初始化时运行一次。假设DOS格式的磁盘卷已经被格式化,能够跳过此步。

        dosFsVolFormat()的函数使用方法为:

    STATUS dosFsVolFormat(void *device,intopt,FUNCPTR pPromptFunc)

     

         參数1表示要运行格式化操作的卷名。

         參数2表示格式化的选项。是比特映射。即选项的组合。0表示使用默认选项。

    參考帮助;

         參数3表示一个函数。该函数能够提示用户在格式化前改变卷的參数,0表示无函数;

    函数返回格式化成功与否的状态值。图2中此处用dosFsVolFormat(“/DOSA”,0,0)将卷/DOSA格式化。

    格式化后就能够使用了,能够用ll“/DOSA”挂载卷。此时可运行完整性检測,用dosFsShow “/DOSA”显示卷信息。

    运行->devs会发现有/DOSA卷,运行->cd “/DOSA”将当前工作文件夹切换到该卷上。运行mkdir 文件夹名。在该卷上创建一个相应的文件夹。

    运行rm 文件夹名,就可以删除相应文件夹。

    有些函数里的CBIO句柄參数能够用BLK_DEV变量取代,此时系统会自己主动进行转换工作。

             至此,磁盘设备上的文件系统创建完毕。用户能够直接訪问磁盘并进行相关操作。

    展开全文
    weixin_34391445 2017-06-17 16:25:00
  • u011996698 2021-07-08 20:56:38
  • catcher03 2012-03-13 00:38:31
  • 4星
    1.4MB qcj_21 2017-11-03 17:04:16
  • wanxuexiang 2020-08-15 16:47:25
  • u011672712 2018-02-07 16:13:15
  • kulala082 2016-12-20 15:03:06
  • m0_37585897 2021-12-08 15:56:40
  • lixiaojun216 2014-10-13 22:58:22
  • dwd112358 2019-07-21 01:21:56
  • jiangganwu 2018-06-10 22:48:52
  • weixin_30332705 2014-08-05 15:59:00
  • 2.1MB u011672712 2017-12-05 16:21:14
  • st19890625 2016-09-23 15:17:54
  • hairuibeijing 2018-02-03 18:54:38
  • rt201314 2021-07-02 00:57:36
  • wanxuexiang 2020-04-29 21:42:41
  • rt201314 2021-07-16 01:08:19
  • u010383937 2017-05-16 11:02:55
  • yhc1991 2017-06-26 19:59:02
  • LOTOOHE 2017-03-09 10:23:21
  • yhc1991 2015-09-20 18:29:34
  • weixin_42314225 2021-11-18 20:14:10
  • freemervyn 2017-04-15 22:16:47
  • qq_39568121 2021-01-25 14:08:24

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,906
精华内容 1,962
关键字:

vxworks文件类型