关于VxWorks

 VxWorks操作系统

      VxWorks时实时多任务的嵌入式操作系统,它主要包括任务调度、I/O功能、文件系统、中断管理、内存管理、网络功能、内存管理、BSP(系统启动模块)等。它的多任务的实现是由中断驱动的,即在每个系统时钟中断中,实现任务的调度。VxWorks中的任务有优先级的概念。与其它嵌入式操作系统相比,它有如下优点:

1.  任务之间的切换快,任务间通信手段多样;

2.  中断响应的延时短;

3.  内存管理安全:VxWorks把内存分成很多区域,包括内核区、用户区,并且采用虚拟内存管理的方法,这样大大提高了系统的安全性,并且增加了堆栈溢出的判断;

4.  I/O功能丰富,硬件驱动全面;

5.  文件系统强大;

6.  网络功能全面;

7.  对任务的实时监控;

8.  BSP(启动模块)的支持;

9.  多CPU的支持;

10.系统各模块是单独的库,可以根据需要加载。

 

 

下面就详细讲述各部分内容。

 

1. 多任务功能:

VxWorks的任务有优先级的概念,其任务调度也是基于优先级考虑的,是抢占式的,VxWorks的任务有256个等级,0—255,数目越小表示优先级越高。高优先级的任务可以打断低优先级的任务而抢先执行,只有在高优先级的任务执行完后,低优先级的任务才可以执行。其调度算法有两种:完全抢占式的和循环分配式的。完全抢占式的是除了高优先级任务可以打断低优先级任务外,在相同优先级的任务之间,不可以相互打断,并且同优先级任务不是同时执行的,只有等该任务执行完后,与其相同优先级的任务才可以执行;循环分配式除了具有抢占功能之外,相同优先级的任务是可以同时执行的,即系统时间片是在它们之间平均分配的,这样,相同优先级的任务可以同时执行。可以调用kernelTimeSlice()函数来设定该调度方式,并且参数是相同优先级任务执行的时间片。

 

另外任务在执行的过程中,可以调用taskLock()函数来中止任务调度,从而保证该任务的执行不会被其它任务所打断,只有在调用taskUnlock()后才会恢复任务调度。需要注意的是,如果调用taskLock()的任务在调用taskUnlock()之前又被挂起了(可能堵塞在信号量上等),那么系统就会搜索其它任务中优先级最高的那一个,并执行它,而在调用taskLock()的任务恢复执行后,任务调度又会被中止。

 

VxWorks中任务具有很多种状态,如下表所示:

状态

描述

READY

此任务状态在等待执行

PEND

此任务状态是由于一些资源不可用而被阻塞

DELAY

此任务状态是休眠一段时间

SUSPEND

此任务状态是挂起

BREAK

此任务状态是停止(暂停),通常是在任务中设置了断点。

各种状态的组合

详细请见原文档

为了防止任务被误删除,VxWorks还提供了taskSafe()函数和taskUnsafe()函数,调用taskSafe()的任务不能被删除,应用在其它地方调用taskDelete()函数时会出错。只有该任务在调用了taskUnsafe()后,任务才能被删除。另外,VxWorks还可以对任务的优先级动态的修改,即可以在执行过程中,调用taskPrioritySet()函数对任务的优先级进行修改。对于任务的创建,VxWorks还提供了不同的方法,用户可以调用taskSpawn()函数在创建完任务后立即执行它,或者调用taskCreate()taskActivate()函数把创建任务和执行任务分成两步来实行,即在调用taskCreate()后,任务只是被创建而没有执行,所以用户可以在需要的时候调用taskActivate()来恢复任务的执行。下面是VxWorks任务相关函数一览表:

函数名

功能

kernelTimeSlice( )

控制轮询式调度程序

taskLock( )

取消任务的再调度

taskUnlock( )

允许任务的再调度

taskSpawn( )

生成(创建和激活)一个新任务

taskCreate( )

创建一个新任务,但不激活它。

taskActivate( )

激活一个已经创建的任务

taskSuspend( )

挂起一个任务

taskResume( )

恢复挂起任务的执行

taskRestart( )

重新开始一个任务的执行(即从头执行)

taskDelay( )

延时任务,延时单位是时间片

taskIdSelf( )

得到调用任务的id(正在运行的)

taskIdVerify( )

验证一个指定任务是否存在

taskOptionsGet( )

获得用户自定义任务参数

taskOptionsSet( )

设置用户自定义任务参数

taskIdListGet( )

将所有活动状态的任务id填写到个数组中

taskInfoGet( )

得到一个任务的信息

taskPriorityGet( )

获得任务的优先级

taskPrioritySet( )

改变任务优先级

taskRegsSet( )

设置一个任务的寄存器(但是不能被当前任务使用)

taskIsSuspended( )

检查一个任务是否在悬挂状态(suspended.)

taskIsReady( )

检查一个任务是否准备运行就绪

exit( )

结束正在运行任务,释放内存*

taskDelete( )

结束制定的任务,释放内存*

taskSafe()

保护当前任务,防止被删除

taskUnsafe( )

取消taskSafe( )操作,即能够删除当前任务

nanosleep( )

延时任务,延时单位是时间片

         另外除了用户创建的任务外,VxWorks本身也创建了很多系统任务。包括BSP(系统启动)任务、异常处理任务、系统登记任务、Telnet任务、代理任务、RPC(远程进程调用)任务等。

       其中BSP任务在系统启动完成后就自动被删除;异常处理任务是当系统因非法指令、总线错误等而产生异常时,系统会调用该任务来处理,系统处理是挂起发生异常的任务,保存其运行状态,而其它任务的执行状态不变,用户也可以自定义异常处理函数,方法是使用信号处理功能,这样发生异常时,系统会调用用户定义的信号处理函数来处理;系统登记任务是系统用来实现内部消息在当前运行任务上下文中的登记的,它使得消息的登记不用通过I/O来实现,从而提高了效率;telnet任务是用来实现远程机器登录的,它检测用户名、密码等,在用户登录完成后,该任务即被删除;代理任务是用来实现本机和目标服务器通信使用的,当目标服务器需要操纵本机(发送、获取信息等)是通过该任务来实现的,当目标服务其需要数据时,它会将请求发送给该任务来获取数据;RPC任务是用来处理远程机器对本机(服务器)进程调用的,远程机器通过后台程序来发送调用请求,而RPC任务就是处理该请求。

       与Windows下类似,VxWorks就任务模块为开发者提供了钩子(hook)功能,开发者可以在任务的创建、删除、或者任务切换时设定钩子函数,这样在每个任务创建/删除时,系统都会调用用户设定的钩子函数,从而用户可以监测系统中每个任务的创建、删除等。

       另外,用户可以调用exit()、return;来退出本任务的执行,可以调用taskDelete()来删除其它任务从而中止其执行。值得注意的是,在调用exit()退出本任务的执行时,本任务所占用的内存并不会被释放,更为严重的是,如果本任务正在使用信号量等资源,那么其它想获得该信号量的任务将永远不会得到它,从而可能会永远挂起。任务在执行过程中,如果为了不被中断所打断,可以调用intLock()来屏蔽所有中断,而调用intUnlock()将解除屏蔽。

      

VxWorks为任务间的通信和同步提供了丰富的手段,包括信号量、消息队列、管道、信号等。

         VxWorks信号量是分为三种:

(1)         二进制形式的:最快的也是最简单的信号量,用于任务间同步;

(2)         公用体互斥的:一种特定的二进制信号量,用于公用体互斥,并且具有优先级继承的功能,删除安全。

(3)         可计数的信号量:与二进制形式的类似,所不同的就是同时有多个信号量用于同步。

一个信号量有两种状态,满的(可获取)和空的(不可获取),用户可以调用semTake()

来获取一个信号量,如果该信号量当前状态是满的,则函数返回成功,否则该任务挂起,挂起时间由用户指定,可以永远挂起直到获得该信号量。因此任务在使用完信号量后,一定要调用semGive()释放,否则其它任务将无法获得该信号量。

可以有多个任务同时挂起在同一个信号量。在出现这种情况时,如果拥有该信号量的任务释放了它,那么下一个获得该信号量的任务由两种规则决定:FIFO(先进先出)和按优先级顺序。如果是按FIFO规则,那么第一个等待该信号量的任务将获得该信号量而执行;如果是按优先级顺序,那么挂起在该信号量上的优先级最高的任务将获得该信号量而执行。

任务如果在指定时间内没有获得指定的信号量,那么任务将继续执行,而semTake()函数将返回超时错误。

 需要注意的是,有可能会出现下面的非正常情况:

Task3

Task3

Task3

 


 

Task1

Task1

Task1

优先级

Task2

Task2

           等待信号量1                                     释放信号量1         

pos5  pos2         pos1           pos3  pos4           时间

      如上图所示,其中优先级顺序是,task3 > task2 > task1,task1获得了信号量1,而task3调用semTake()想获得该信号量,挂起;正常情况下,task1在虚线框pos1处释放该信号量,从而task3也可执行,但在task1执行过程中,被优先级更高的task2在pos2处打断,而task2在pos3处退出,从而task1在pos4处才能释放该信号量,而task1也只有在pos4处才可以执行。但这是不正常的,因为task1的优先级比task2高,而task1却由于task2的执行而被推迟执行,这样就出现了“优先级倒置”的情况,公用体互斥信号量就是为了解决此问题的。

            在当前任务获得某公用体互斥信号量时,如果有其它任务也想获得该信号量从而挂起,并且它们有些优先级是比当前任务要高的,那么当前任务的优先级将变成跟其中优先级最高的任务一样。这样就防止被其它低优先级任务(但高于当前任务)所打断 。如下图所示:

Task3

Task1

Task1

Task3

Task1

                                                          

                    优先级

Task2

Task2

                                             

                                        优先级升高                          优先级恢复

Task1

                                               pos5           pos1         

                                                                                                                                 时间

 

       在pos5处task1优先级跃迁成与task3一样,在pos1处task1释放完信号量1后,

其优先级又恢复正常,task2没有得到机会执行。

           计数信号量其实就是多个二进制信号量,即该信号量的个数不止一个,可以有多个

任务同时获得它。比如创建时指定的计数器是3,那么在任务调用semTake()函数时,系统会判断当前信号量个数,如果是>0的,那么就可以获得,否则挂起。只要当前有不超过3个任务获得该信号量,那么semTake()函数都是成功的。

       VxWorks提供了 semFlush()函数,可以释放指定的信号量,并且挂起在该信号量上的所有任务全部恢复正常执行。

       需要注意的是,semGive()函数可以在中断函数中调用,但是semTake()函数则不可以,因为semTake()函数可以挂起,而中断是不能被挂起的。

 

       VxWorks的消息队列为任务间的数据传输同样提供了便捷。VxWorks消息队列是FIFO的,并且消息大小和队列总长度可以由用户在创建消息队列时指定。用户调用 msgQSend()函数向指定消息队列中发送消息,如果当前消息队列没满,那么消息被放进队列中,函数成功返回;否则根据用户传进的参数,调用msgQSend()的任务可能被挂起、立即返回或延时一段时间后返回。类似的,用户调用msgQReceive()函数从指定队列获得消息,如果当前消息队列不是空,那么系统把消息拷进用户指定的buffer中,成功返回;否则根据用户传进的参数,调用msgQReceive()的任务可能被挂起、立即返回或延时一段时间后返回。

       同样,对于挂起在消息队列的任务,可以有两种方式决定首先恢复哪一个执行:FIFO和按优先级顺序。

需要注意的是,msgQSend()函数可以在中断函数中调用,但是msgQReceive()函数则不可以,因为msgQReceive()函数可以挂起,而中断是不能被挂起的。

 

VxWorks中的管道类似于消息队列,也是先进先出的。所不同的就是任务可以同时从多个管道中发送数据(或从多个管道中获得数据),从而挂起在多个管道上,而其中任何一个管道如果满足了任务的要求,那么任务就会恢复执行。

VxWorks中信号一般被用来作为异常处理,用户可以把自己的处理函数通过调用sigvec()连接在特定的信号上,所以信号与中断是类似的,例如总线错、非法指令等都会置上一个特定的信号。

        

 

2.VxWorks的中断管理

VxWorks的中断延时短,可以满足实时的要求,而用户可以用C语言编写中断服务程序,而无需掌握汇编。用户只用调用intConnect()函数即可把自己的中断服务函数和特定的中断挂接起来。事实上,VxWorks并不会把用户的中断函数地址直接填到指定的中断向量处,而是在VxWorks本身的中断服务函数中,调用用户的中断函数。

需要注意的是,用户中断函数所使用的栈和应用任务的栈并不相同,而是由用户指定的另外一段空间,这样在一定程度上保证了系统的安全性。

用户可以调用intLock()屏蔽所有中断,从而保证当前的中断服务程序不被打断。调用intUnlock()解除中断。

 

 

3. VxWorks的内存管理

           VxWorks中有虚拟内存的概念,内存是分页管理的。即用户所操作的内存地址实际上是虚存,实际物理内存对于用户而言是不可见的。 在VxWorks中,内存被分成许多域,有内核域、应用域。内核域用来执行操作系统内核代码和存放操作系统内核数据(如信号量、任务控制结构等),应用域用来 执行用户任务代码和存放用户任务数据。各个域之间的数据是不可见的,除非有共享数据区,并且对用户而言,各个域的内存地址分布有可能是一样的,逻辑上是重叠的,但是对应到物理地址,是不一样的。

  每个应用域都有自己的堆和栈,而且都有内核域在本域中的映像。在一个应用域中,可以创建多个任务,它们共用该应用域的内存空间,它们的堆和栈都是在本应用域中的。简单地说,应用域类似于其它操作系统中的进程,而任务则类似于线程,任务是VxWorks中调度的最小单元。

每个应用域都有自己的虚拟地址<—>物理地址的映射表,用户的任何内存操作都要通过该表转换到物理内存地址 后执 行。而用户可以设定某些内存页面的属性为只读、读写等。例如中断向量表区、程序区等应该设成只读属性。如果程序中有对只读内存进行写入操作时,那么系统会抛出异常。

系统内存和I/O地址资源的分配在00region.sdf中定义,但不管怎样,都要包含一个kernelMemPool的内存域,这是内核域。

VxWorks支持标准内存分配接口:malloc(),free()和realloc(),并且分配的内存只是在本应用域中。应用域的内存空间可以根据需要增大或者缩小,这实现用户可以手动完成也可以由系统自动完成。需要注意的是,内存相关函数不可以在中断中调用,因为其中有信号量的操作。

另外,各个应用域可以有共享的数据区域,其大小可由用户指定,这样,这些应用域中的所有任务都可以对该共享数据区域进行读写操作。各个应用域还可以有共享代码库,这样这些应用域中的所有任务都可以调用库中代码,但库中的数据对各应用域是不可见的。应用域调用Attach()/Deattach()来把自己和某个共享代码库连接/断开。在一个共享代码库可以从内存中删除前,必须保证其没有被任何一个任务所使用。

应用域可以被动态的创建、卸载。当一个应用域被删除时,其中所有任务都停止运行,并从内存 中删除;而如果其中所有的任务都被删除后,该应用域将被自动从内存中删除。

VxWorks提供了API接口来察看某个应用域中内存的使用状况,如memShow()。

应用域中的任务在执行时可能有两种状态,用户态 和超级用户态,用户态只能操作本应用域中的内存,而超级用户态可以操作包括内核域在内的所有域中的数据。任务在调用系统API函数时,将自动变成超级用户态,而在调用完成后,将恢复为用户态。创建任务时,系统默认任务状态是用户态,但用户也可以手动设置某任务的状态为超级用户态,但前提是该任务所在的应用域必须是特权态(privilege)。

 

 

4.I/O功能及硬件驱动

       VxWorks提供了丰富的I/O功能(包括低层硬件驱动)供使用,包括:硬盘驱动,键盘驱动,网卡驱动,显卡驱动,软盘驱动和并行口驱动等。并且驱动程序还可以由开发者自己动态添加、删除而不用重新启动系统。用户可调用iosDrvInstall()函数来添加自己的硬件驱动,从而系统在操作相应设备时,会调用用户的驱动来实现。

       VxWorks提供的I/O接口统一简单,如下表所示:    

函数名

功能

create()

 创建设备

remove()

删除设备

open()

打开设备

close()

关闭设备

read()

从设备中读取数据

write()

向设备中写入数据

ioctl()

控制设备(例如设置波特率等)

 

           另外,VxWorks还可以在内存中创建虚拟磁盘,方法是调用ramDevCreate()函数。可以指定内存的起使位置和大小、扇区大小等。

           VxWorks还提供了对网络文件系统设备的支持,用户可以调用nfsMount()函数来打

开远程机器上的某一文件,在调用标准I/O接口对其进行读写操作。

       VxWorks还支持标准的I/O函数,printf和sprinf等

VxWorks把所有的I/O设备都看成是文件,在用户打开一个设备时,如果成功函数会返回其ID,用户以后对该设备的读、写等操作都通过该ID来实现。该ID对于其它所有的任务都是可见的,其它任务也可以通过该ID对该设备进行操作。

       注意:ID值0、1、2是系统保留的,分别用来表示标准输入、标准输出和标准错误输出设备,当然用户可以指定自己的标准输入、输出和出错输出设备。

5.文件系统

VxWorks提供了强大的本几文件系统供使用。提供了与MS-DOS兼容的FAT32文件系统,另外还提供支持硬盘、CD-ROM、磁带设备和FLASH的文件系统,并且在一个VxWorks系统中,允许多个文件系统同时存在。VxWorks文件系统中,文件名可以设成是大小写敏感的,并且长度不限于DOS中的8+3。

VxWorks中,文件的读写接口是标准接口:fopen(), fclose(), fread(), fwirte(), fseek()。

VxWorks支持磁带文件系统,对于磁带,其实是被看成一个大文件来读写,没有文件夹。所有对该文件的操作都是从磁带起始位置开始的。

另外VxWorks提供的TrueFFS文件系统,是支持FLASH设备的;VxWorks提供的TSFS文件系统,是支持 网络功能的,它可以用来实现和Tornado服务器程序通信,从而在服务器上存取本机文件。

 

 

6.网络功能(需要再看network program 文档)

VxWorks的网络功能是通过socket来实现的,它提供了与BSD一致的socket接口。即socket(), read(), write(), close(),connect()等。并且同样可以使用TCP或UDP协议作为传输层的传输协议。所谓socket就是对TCP或UDP协议、IP地址和端口的绑定,它是唯一的。

VxWorks的网络功能也是很强大的,它提供的网络驱动接口MUX,运行在IP层和数据链路层之间,从而用户可以在MUX中加进自己的协议,并且用户还可以增加自己的网络驱动。VxWorks的网络功能主要包括下面的内容:

(1)       数据链路层

(2)       TCP/IP协议族

(3)       网络配置协议族

(4)       选路协议

(5)       SOCKET API接口

(6)       DNS(域名解析系统)

(7)       简单时间传送协议和远程进程调用

(8)       远程文件的存取和PING、TELNET功能

   

     下面详细讲述各部分内容:

(1)      数据链路层

        数据链路层是硬件驱动层,它是上层协议的基础,VxWorks给数据链路层提供了三种驱动:以太网驱动;SLIP(串行线协议驱动);共享内存网络驱动。其PPP协议的实现包括:PAP(PPP认证协议)、IPCP(PPP以太网控制协议)和PPP协议。它所实现的PPP协议有下面的特点:

①     客户端和服务器连接功能的支持;

②     有16个PPP连接可以被同时激活;

③     可以指定控制字符以免被底层MODEM软件误解;

④     VJ压缩功能,可以把40 bytes的TCP/IP头压缩至3~8bytes;

⑤     PPP协议的地址控制和协议字段同样有压缩功能;

⑥     具有PPP连接状态查询功能,这样用户可以监测PPP连接;

⑦     IP地址协商功能,一个主机可以通过协商为另一个主机分配IP地址;

⑧     具有数据回显和数据应答功能;

⑨     用户可以为PPP的连接和断开设置钩子函数,这样用户就可以知道每一个PPP连接和断开的过程;

⑩     提供了握手认证协议和口令认证协议功能以及代理服务器路由功能。

它的不足之处是:

最多只有16个PPP连接;并且驱动是串口驱动,没有提供对MODEM或者以

太网卡驱动的支持;只支持标准的CHAP(客户握手认证协议)而不支持微软的扩展CHAP,如果想要支持扩展CHAP,只有使用WindNet的PPP产品。

      SLIP和PPP协议都是用于两台终端之间的互相通信,但它们各有优缺点,如下表所示:

 

    协议

功能

SLIP

PPP

效率

支持上层协议

IP

IP及用户自定义

可扩展性

错误校验

有(CRC 校验)

对连接的管理

有,可对主机之间的连接进行管理,例如修改选项和身份认证等,选项协商为主机之间修改各自的选项提供了机会,例如,一台主机可以通过PPP协议协商来限制另一台主机的PPP连接数目

 

需要注意的是,PPP所提供的身份认证功能,客户端会不停的向服务器端发送

ID/PASSWORD直到通过了认证或者连接中止,并且密码是以明文方式发送的,这样对于重复攻击没有防御能力。而CHAP协议具有更好的安全性,它是需要客户端通过哈希算法根据一定的数据算出一个值,发送到服务器端,服务器把该值与自己计算的值相比较,从而决定能否通过认证。

         另外,VxWorks还提供了DES加密算法包,可对用户密码进行加密,这样为认

证过程又提供了安全性。用户还可以调用usrPPPInit()来重新配置PPP结构中的选项,例如可以设置建立一个PPP连接的超时时间。用户调用pppInit()也可以达到同样的目的,与usrPPPInit()不同的是,pppInit()可在运行时调用,其传入的参数是一个PPP_OPTIONS的结构,修改其中相应的字段即可修改PPP连接参数。或者用户也可以修改配置文件来修改PPP参数。

     VxWorks向用户提供了众多的参数供修改:是否显示调试信息;是否在协商IP地址成功后,把对方添加进路由表;是否允许IP地址协商功能;是否使用密码数据库作为密码认证。另外,用户可以调用pppInfoGet()来判断一个PPP连接是否成功,有两种途径来删除一个PPP连接:

从对方主机接收到一个断开请求的数据包;调用pppDelete()。

值得注意的是,重启机器或者删除一个任务并不会断开一个PPP连接,而只会断开TCP/IP的连接。

VxWorks对于PPP的默认设置是,只能作为客户端发送认证信息,而不能作为服务器来验证用户的认证请求。当然用户可以修改默认参数。

VxWorks还提供共享内存网络驱动作为同一台主机上的多个CPU间的通信手段,作为同一台主机上的多个CPU,都有一个单独的IP地址,都可以单独与网络上的其它主机通信,同样,多个CPU之间也可以使用SOCKET互相通信。    

 

(2)      TCP/IP协议族

TCP/IP协议运行于链路层之上,VxWorks除提供对TCP/IP的标准支持外,还有自己的特点。在VxWorks中,TCP/IP参数可以在运行时修 改   ,用户可以手动修   改路由表,通常在系统中,这是由选路协议自动修改的。VxWorks提供的可修改的TCP/IP部分参数如下表所示:

 

 

 

参数宏

意义

TCP_SND_SIZE_DFLT

TCP默认发送缓存大小

TCP_RCV_SIZE_DFLT

TCP默认接收缓存大小

TCP_CON_TIMEO_DFLT

TCP默认连接超时时间

IP_TTL_DFLT

IP包的最大HOPS数目

IP_QLEN_DFLT

IP包的队列大小(即最多可同时存放多少个IP包)

 

    VxWorks提供的众多参数为开发者提供了最大的灵活性,但是用户在修改TCP的接收窗口大小(Window size)时,必须在调用connect()或listen()之前,因为窗口大小是在调用connect()时协商决定的,所以如果在调用之后修改数据包窗口大小,就没有任何作用,因为这时窗口大小已协商完毕。VxWorks默认的接收窗口大小是258,111 bytes,当接收缓存满时,window size自动变为0。此外,VxWorks提供的丰富的接口又为开发者提供了便捷,部分函数如下图所示

函数名

功能

ipAttach()

绑定一个IP地址到本机

ipDetach()

去处绑定的IP地址

 ifMaskSet()

设置子网掩码

  MRouteAdd()

添加路由

   mRouteDelete()

删除路由

 

VxWorks默认包含四个协议模块:TCP、UDP、ICMP、IGMP,用户也可以根据自己的需求添加或减少协议。TCP和UDP都是传输层的协议,但是它们有很大的不同,如下表所示:

        协议

特征

TCP

UDP

传输形式

字节流

数据报文

开销

可靠性

传输数据前是否需要建立连接

需要

不需要

 

VxWorks中协议栈所用的内存空间是单独分配的,是以扇区的形式分配的。每个扇区的大小和扇区的总数决定了协议栈所用的内存大小。它是存放在表clDescTbl中的,用户可以修改它。而且VxWorks提供了多种扇区,如64 bytes大小的,128 bytes大小的等。用户也可以指定自己的扇区大小,但是不能有两种扇区,它们的大小在2的两个连续幂之间,如34和49不能同时指定,因为它们都位于32和64之间。

 

VxWorks用mBlk和cBlk结构来存放协议栈所用的数据。mBlk结构变量以链表形式存储,这样只用知道链表头,就可以得到全部数据。mBlk结构中包含一个cBlk结构变量,从而多个mBlk结构可以共享一个cBlk,进而共享其数据,这样提高了数据传输的效率,而不用拷贝。使用cBlk结构而不直接使用指针存储数据的好处是,cBlk结构中保含了一个变量,用来记录有多少mBlk公用了它,从而在释放其数据空间时可以相应处理。如果cBlk被引用的数目减少到0,那么它将自动被从内存中删除。

用户还可以调用netMblkClChainGet()来分配一个mBlk块,并设定其内容,在用户使用完该块后,调用netMblkClChainFree()来释放它。

VxWorks还提供了ping功能,接口函数是ping(主机名,次数,选项)。用来查看和远程的主机是否可以连通。如果ping发送的数据包无法到达目的主机,那么接收到该数据包的最后一个路由将返回一个ICMP错误报文。

在VxWorks中,除调用API接口来绑定IP到本机、设置子网掩码等外,还可以从boot行设定,格式是:e = IP:子网掩码

对于广播地址,VxWorks有两种认定,IP地址中,除子网掩码外的所有bit均为1或0。但RFC标准规定的是应该全为1,VxWorks这样作是为了和一些老的系统相兼容。

路由表中的条目可以分为三种:本机路由,静态路由和由RIP协议动态添加的路由。用户可以调用routeProtoPrioritySet()来设定各种路由的优先级。

VxWorks还为用户提供了ARP 代理服务器功能,该代理服务器在接收到子网内的ARP请求时,会修改该ARP数据包,把自己的物理地址写进去,再以广播形式发送。

另外,VxWorks不支持二级代理功能。用户可以调用proxyPortFwdOn()来设定UDP协议的广播端口,可以调用proxyPortFwdOff()来关闭该广播端口。

在VxWorks中,用户有两种方法在一个子网内分配IP地址:手动和自动(包含INCLUDE_SM_SEQ_ADDR宏)。采用自动方式时,除了Server外的其它机器的IP地址从Server的IP地址开始依次累 增。VxWorks还提供了网络字节排序(低字节在前,高字节在后)和主机字节排序(相反)的转换宏。

 

(3)      网络配置协议

VxWorks提供对包括BOOTP、DHCP和SNMP协议的支持。DHCP协议和BOOTP协议都可以为主机分配IP地址,但是DHCP是动态分配IP地址的,而BOOTP分配的地址是固定不变的。

BOOTP服务器有自己的数据库文件,内容是:BOOT目录和BOOT时所传输的启动文件;可以从本服务器BOOT的主机IP地址、物理地址,主机名和子网掩码。当一台客户端主机向本服务器发送BOOT请求时,服务器首先根据其物理地址从数据库中查找匹配的条目,如果找到,那么判断该主机有无IP地址,如果没有则给它分配相应的IP地址;如果没有找到匹配条目,那么丢弃该请求。服务器在查找BOOT文件时,首先根据 文件名.主机名来查找文件,如果没有找到,则查找文件名文件,如找到则发送该文件。

DHCP服务器不仅可以接收DHCP消息,而且还可以接收BOOTP消息,VxWorks对DHCP的实现,在客户端主机IP地址改变时,DHCP服务器必须重新连接主机,否则会导致连接中断,解决的办法是,用户可以配置DHCP,使它可以为主机分配永久IP地址。

VxWorks为用户提供了接口dhcpOptionSet()来修改DHCP的参数,比如IP地址保持不变的最短和最长时间。另外,DHCP动态分配的IP地址优先级低于用户自己手动分配的IP地址。用户调用dhcpBind()来给各主机分配IP地址。VxWorks实现的SNMP协议支持标准的管理信息库(MIB),个人也可以扩展该库。

 

(4)      选路协议

         VxWorks提供对RIP、OSPF选路协议的支持,RIP协议的缺点是TTL数不能超过15,     这在现在某些情况下是不够使用了。OSPF则没有此限制,但是OSPF的复杂性使得配

置OSPF服务器变得很麻烦。

用户可以调用ripRouteShow()函数来显示路由信息。该函数可以打印以下信息:

被数据包广播到的路由;

接力传送该数据包的路由;

相应的子网掩码;

该路由的超时丢弃数据包值;

标志值。

 

(5)      socket API接口

    VxWorks提供和BSD一致的Socket接口,而且,在VxWorks中,socket不仅可以用来实现以太网上不同主机的任务之间的通信,还可以用来实现本机任务之间的通信。

多播功能是属于IP层的,但是一般应用使用UDP来实现它。VxWorks提供的多播接口包括:mCastSend(), mCastRcv()。主机要接收/发送多播数据,必须首先加入该多播组。

VxWorks提供的zbuf-Socket接口,使得应用程序和网络层之间无需拷贝数据,而只是简单的移动指针即可。这样提高了系统效率,降低了开销,实际上,zbuf-socket的缓存是以字符串指针数组的形式存放的。

 

(6)      DNS

VxWorks提供对DNS的支持。用户可以调用hostAdd()手动添加域名和地址的映

射,可以调用hostShow()查看主机名和IP地址的映射表。可以调用resolvGetHostByName()函数来根据主机名获得相应的IP地址,可以调用resolvGetHostByAddr()函数来根据IP地址来获得相应的主机名。

 

(7)      SNTP和RPC

VxWorks提供对SNTP协议的支持,它可以用于客户端来查询其它机器上的时

间,或者服务器向其它主机提供时间。另外,RPC(远程进程调用)功能只能在任务中使用,每个任务在调用RPC之前都必须调用rpcTaskInit()函数。

 

(8)      远程文件存取和telnet

VxWorks提供的远程文件存取功能所使用的协议是RSH和FTP。另外用户也可以

使用NFS(网络文件系统)来实现文件的传输。其不同点是:RSH/FTP协议使用netDrv驱动,在传送文件时会把整个文件传送过来,存在本机内存中,用户修改完文件后,再传送回去;而NFS使用nfsDrv驱动,它只把用户要修改的部分传送过来,修改完后传送回去,提高了效率。

用户可以把本机配置成为FTP服务器,可设定登录密码。VxWorks提供telnet功能,但是telnet的目的主机也必须是运行的VxWorks系统。

 

 

7.对任务的实时监控    

       VxWorks提供了对系统的实时监控(Spy)功能,它可以提供每个任务运行所耗时间信息、系统所花在中断上的时间信息以及CPU的空闲时间等,其单位是时钟周期,并可以以百分比的形式显示。更强大的监视工具(仿真器)是WindView,用于程序调试。

这样可以帮助用户分析各个任务以及中断的执行状态是否正常。

 

  

8.BSP模块的支持    

       BSP模块主要用于系统的初始化,包括硬件的初始化、加载系统库并加载应用程序从而运行整个系统等,它可以被掩膜到ROM中,从而不会被修改。另外,sysLib和sysAlib是必须加载的,因为它们提供了对各种硬件目标板的支持,他们包括了硬件初始化、中断处理、硬件时钟和定时器管理、内存的映射和大小改变功能等。

 

 

9.多CPU的支持

   VxWorks的一个特点就是对于多CPU有较好的支持,运行在多个CPU上的任务可以通信,这是由VxMP模块实现的,采用共享信号量和共享消息队列以及共享内存管理的方法。采用共享信号量可以同步不同CPU上的多个任务,就像在本机上使用一样。采用共享消息队列可以让在不同CPU上的任务之间交换数据。采用共享内存可以让在不 同CPU上的任务之间共享数据。

 

 

10.系统灵活性强

     VxWorks强大的灵活性体现在它的各个功能模块都是单独的库,可以根据需要在运行时动态加载。比如任务管理库是taskLib,信号量库是semLib,中断管理库是sysLib和intLib,网络库是sockLib,I/O库是ioLib等,这些库可以根据需要在运行时动态加载、卸载,从而增强的系统的灵活性,节省了系统空间。

 

11. 其他

VxWorks还有其他操作系统所共有的功能,为开发者提供了方便。比如看门狗功能,可以在系统进入死机状态时,给用户以处理的机会。

猜你喜欢

转载自blog.csdn.net/ds1130071727/article/details/80485231