vwoks编程手册.docx
《vwoks编程手册.docx》由会员分享,可在线阅读,更多相关《vwoks编程手册.docx(20页珍藏版)》请在冰豆网上搜索。
vwoks编程手册
1.VxWorks653运行时系统
1.1.运行时层
一个vxworks653模块由下面四层组成:
■coreOS—必需
■partition—至少需要一个(vThreads或COIL-based),每个都在一个分区的操作系统之中
■APEXsharedlibrary—ARINC653应用所需
■POSIXsharedlibrary—POSIX应用所需
1.1.1.CoreOS层
核心操作系统提供服务给分区。
缺省的,核心操作系统使用ARINC653规范中的时间抢占的调度(TPS)来调度分区。
Vxworks653的核心操作系统还可以采用APPS调度策略在TPS调度的空闲时间内调度优先级抢占调度(PPS)使能的分区。
核心操作系统提供给每个VThreads分区操作系统的服务包括:
●分区系统资源
●调度分区
●代表分区的操作系统执行trap异常
●定义和强制分区边界
●装载分区
●使用端口和通道在分区间传递消息
●处理I/O
●代表应用完成系统调用
●支持分区的调试
●监控分区和系统的健康
1.1.2.vThreads层
vThreads分区操作系统在核心操作系统分配给该分区的时间内调度vThreads中的线程。
vThreads不直接与设备交互,而是通过核心操作系统的系统调用。
1.1.3.APEX层
构建在vThreads之上,遵循ARINC653规范,并且提供相应功能和API。
1.1.4.POSIX层
构建在vThreads之上,遵循用于实时扩展的POSIX标准(1003.1b)。
1.2.装载和启动
当目标板加电时,按照下面的步骤进行装载和启动
●初始的启动码装载核心操作系统,分区操作系统,共享库,以及应用
●核心操作系统初始化自身,启动它自己的子系统
●核心操作系统创建分区
●核心操作系统启动分区调度器,并且让应用初始化自身
核心操作系统可以在初始化完成之后下载在线装载的应用程序到分区。
应用可以在分区运行之时装载到分区。
1.3.运行时模型
核心操作系统处理来自每个分区的系统调用,并且在运行系统调用前校验每个系统调用的语句。
使用vThreads分区操作系统的应用拥有完全的vThreads任务间通信机制。
APEX库提供了遵循ARINC653规范的分区管理,进程管理以及时间管理;为分区间通信提供了消息,通道,端口;为分区内通信提供缓冲区,黑板,信号量以及事件。
端口映射允许在VxWorks653模块之外通信。
2.开发APEX应用
APEX是位于应用程序和支持ARINC653规范的操作系统之间的API。
对于VxWorks653,操作系统是vThreads分区操作系统和核心操作系统。
APEX给vThreads分区提供了时间、进程管理以及管理周期性和非周期性进程的能力。
APEX提供如下服务:
●管理分区
●管理进程
●管理时间
●与其他分区通信(使用消息,端口和通道)
●分区内的通信(使用缓冲区,黑板,信号量以及事件)
●监控健康
2.1.分区管理
分区的管理包含分配分区内存以及依据ARINC653规范初始化分区。
2.1.1.分配分区内存
每个分区的资源分配都定义在基于XML的配置和编译过程中,根据指定在该规范中的分区需求,为每个分区分配唯一的物理内存。
通过禁止对超过该分区的内存区域的写访问来确保内存分区。
2.1.2.初始化分区:
冷和热启动
冷启动:
当VxWorks653模块加电并且创建分区时,使用冷启动分区操作模式。
在冷启动模式下,分区对象被分配并且初始化。
热启动:
热启动分区操作模式导致一个分区重新初始化或者由于遇到错误重新启动。
在热启动模式下,持久数据不会重新初始化,分区代码也不会重新装载。
每个分区所使用的资源(如通道、进程、队列、信号量或事件等)在系统编译时指定。
在分区的初始化阶段,创建分区所需的资源,然后分区进入NORMAL模式。
2.1.3.分区属性
分区属性定义在XML配置文件中。
固定的分区属性包括:
●标识符:
定义在VxWorks653模块上唯一的分区标识符。
●内存需求:
分配给分区的物理内存
●周期:
分区的激活周期。
用来确定核心操作系统的整个时间帧内的分区激活的运行时位置。
●持续时间:
分区的每个周期内核心操作系统给予的处理器时间。
●关键级别:
分区的RTCA/DO-178B认证级别。
●通信需求:
分区与其他分区通信的通信通道
●分区健康监控表(健康监控配置):
健康监控器对于故障的动作指令。
2.1.4.获得分区状态
GET_PARTITION_STATUS函数可以获得当前情况下的分区状态。
typePARTITION_STATUS_TYPEisrecord
IDENTIFIER:
PARTITION_ID_TYPE;
PERIOD:
SYSTEM_TIME_TYPE;
DURATION:
SYSTEM_TIME_TYPE;
LOCK_LEVEL:
LOCK_LEVEL_TYPE;
OPERATING_MODE:
OPERATING_MODE_TYPE;
START_CONDITION:
START_CONDITION_TYPE;
endrecord;
typeOPERATING_MODE_TYPEis(IDLE,COLD_START,WARM_START,NORMAL);
typeSTART_CONDITION_TYPEis(NORMAL_START,
PARTITION_RESTART,
HM_MODULE_RESTART,
HM_PARTITION_RESTART);
Where:
NORMAL_STARTisanormalpower-up.
PARTITION_RESTARTiseitherduetoCOLD_STARTorWARM_STARTbythepartition
itself,throughtheSET_PARTITION_MODEservice.
HM_MODULE_RESTARTisarecoveryactiontakenatmodulelevelbytheHM.
HM_PARTITION_RESTARTisarecoveryactiontakenatpartitionlevelbytheHM.
2.1.5.设置分区模式
SET_PARTITION_MODE函数可以设置分区模式为IDLE,COLD_START,WARM_START,NORMAL。
其中
IDLE模式:
分区关闭。
分区未被初始化,没有进程正在运行,但是分配给该分区的时间窗口未被改变。
COLD_START模式:
分区重启使用冷启动初始化。
WARM_START模式:
分区重启使用热启动初始化。
NORMAL模式:
激活的进程被调度。
2.1.6.控制分区中的抢占
进程的LOCK_PREEMPTION函数可以为分区中的抢占上锁。
该函数增加了分区的锁级,使得进程不能在分区中重调度。
当进程访问临界区时,或资源被同一分区中的多个进程共享时,这个能力十分重要。
LOCK_PREEMPTION函数不会影响其他分区的调度。
如果一个位于临界区的进程由于分区窗口结束而被中断时,当分区再次运行时仍然是该进程最先运行。
UNLOCK_PREEMPTION函数可以解锁分区的抢占。
这个函数降低了分区的锁级,仅当锁级达到零时,进程的重调度才能恢复。
2.1.7.分区调度
对于时间分区,ARINC653提供了两级调度机制。
在核心模块级,采用预先确定的基于时间窗的循环调度算法来调度各个分区,分区没有优先级。
核心操作系统根据每个分区的周期与持续时间信息,维护一个固定时间长度的主时间帧,该主时间帧的时间长度为所有分区周期的最小公倍数。
静态调度算法为每个分区生成该主时间帧内相应的分区调度窗口,每个分区调度窗口由从主时间帧开始的偏移和期待的持续时间来定义。
分区的调度窗口事先定义在配置表中。
每个分区在其分区调度窗口内被激活并占用CPU,并保证每个分区在其调度窗口内运行时不被其他分区打断。
主时间帧在模块的运行期内周期性的重复,每个主时间帧中拥有相同的分区调度窗口执行次序。
2.2.进程管理
APEX进程是包含在APEX分区内的编程单元。
同一分区内的进程可以并发执行。
进程由可执行程序、数据和栈、程序计数器、栈指针以及优先级期限组成。
进程管理包含创建进程、改变进程当前优先级、得到进程的当前状态、得到进程ID、挂起和恢复进程、停止和启动进程、控制抢占等函数。
2.2.1.进程类型
●周期性进程
●非周期性进程
2.2.2.进程调度
在分区级,调度单元是APEX进程。
每个进程拥有优先级,调度算法是优先级抢占的。
分区级操作系统总是选择处于就绪状态且具有最高优先级的进程获得处理器资源。
如果多个进程拥有相同的优先级,则分区操作系统选择就绪队列中第一个进程。
进程将控制处理器资源直到另一个进程重调度事件发生。
2.2.3.进程状态变迁
2.3.时间管理
2.3.1.调度分区
见2.1.7分区调度
2.3.2.系统时钟时间
系统时钟时间为系统提供了唯一的时间。
GET_TIME函数可以获得系统时钟时间。
2.3.3.请求资源和超时
当进程请求一个APEX资源(例如信号量或事件)时,可以指定下列超时类型之一:
●INFINITE_TIME_VALUE
从不过期。
永久等待
●ZERO_TIME_VALUE
不等待资源。
如果资源不可得,则返回一个错误
●Finitevalueoftimeout
等待一个资源的最大时间
超时单元是SYSTEM_TIME_TYPE类型,纳秒单位。
2.3.4.调度进程
APEX时间管理函数让分区来控制进程。
在每个处理周期(cycle)的末尾,一个周期性的进程请求PERIODIC_WAIT服务来获得一个新的期限。
通过这个进程的下个周期的释放点来计算新的期限。
对于所有进程,TIMED_WAIT服务让进程将自己悬挂一段时间。
在等待时间过去后,进程能够被调度。
REPLENISH服务让进程将它的当前期限推迟一段已过的时间。
分区内的每个进程可以指定一段逝去的时间(叫做时间能力)。
时间能力用来设置处理期限时间,vThreads周期性的评估该时间以确定是否进程在分配的时间内能够完成它的处理。
2.3.5.期限
每个进程关联了一个固定的时间能力,表示分配给它的响应时间用于满足它的处理需求。
期限时间可以确定是否进程能够在它的时间能力内完成它的处理。
可以通过REPLENISH服务增加期限时间,在下一次激活时将创建新的期限。
有三种类型的期限:
●硬期限
如果进程不能在一个指定的时间周期内满足一个硬期限,vThreads将采取补救动作
●软期限
如果进程不能在一个指定的时间周期内满足一个软期限,失效将被记录,并且处理继续
●没有期限
如果进程不能在一个指定的时间周期内完成处理,将不采取任何动作
对于一个周期性进程,当进程的激活周期开始时,期限时间的倒计时也同时开始。
当进程请求PERIODIC_WAIT服务时,倒计时停止(disabled)。
当进程被停止或当它调用REPLENISH或PERIODIC_WAIT服务时,期限时间结束(ended)。
当分区处于除NORMAL模式以外的模式时,倒计时被反激活(deactivated)
对于一个非周期性进程,当进程启动并且分区模式是NORMAL时,期限时间的倒计时开始。
当进程请求一个REPLENISH服务时,期限时间为当前时间加上额外的时间能力。
当进程被停止时或当分区状态不是NORAML时,期限结束。
在图4-5中,周期性线程处于下面的状态:
1.DORMANT
2.RUNNING(orREADYifanotherprocesshaspreemptedit).
3.WAITING
4.RUNNING(orREADYifanotherprocesshaspreemptedit)
5.READYuntilthehealthmonitortakesanaction.Theprocesshasnotcompletedwithinthedeadlineinterval.
1.DORMANT.
2.RUNNING(orREADYifanotherprocesshaspreemptedit)
3.RUNNING(orREADYifanotherprocesshaspreemptedit)
4.WAITING.
5.RUNNING(orREADYifanotherprocesshaspreemptedit).
6.READYuntilthehealthmonitortakesanaction.Theprocesshasnotcompletedwithinthedeadlineinterval.
2.3.6.释放点
周期性线程的第一次释放点相对于主时间帧内的它所在的分区的第一个窗口的开始。
在DELAYED_START服务中使用DELAY,可以将进程调度向后推延。
接下来的释放点基于前面的释放点和进程周期。
2.4.分区间通信
分区间通信包括在一个VxWorks653模块上的两个或多个分区间的通信。
APEX分区通过消息,端口,通道与其他分区通信。
消息可以从一个源端口发送到一个或多个目的端口,进程从这些目的端口读取消息。
消息通信系统的配置在VxWorks653模块配置时进行定义。
2.4.1.用于分区间通信的APEX限制
尽管ARINC653标准制定了下面的通信类型,但是APEX不支持它们:
●多播和客户服务器消息(multicastandclient-servermessages)
●消息确认(acknowledgementofmessages)
2.4.2.APEX消息
APEX消息是连续的数据块。
ARINC653标准使得消息在发送前,分解成小的数据块,单个的送到目的地,然后在交付前进行重组。
但是,VxWorks653仅仅传输完全的消息,避免消息完整性和重传段的检查。
消息可以是固定长度或可变长度。
当消息被发送时,发送者指明长度。
为了适应各种消息长度,消息系统为资源分配最大长度。
消息可以被周期性发送或者按需发送(非周期性)。
任何给定的消息仅仅只能从一个单个的分区发送。
另外,一旦被投递,消息被毁坏,即意味着不太可能请求该消息的旧版本。
2.4.3.APEX通道
通道定义了:
●一个源端口和一个或多个目的端口间的逻辑链接
●消息从源到目的的传输模式
●被发送消息的特征
发送到一个目的端口的消息叫做一个有向消息。
发送到多个目的端口的消息叫做广播消息。
每个通道可以通过配置操作在指定的模式之下(端口和相关的通道定义在XML配置中)。
配置的一致性在编译时间和启动时间进行检查。
对于一个通道,发送端口的大小不能超过任何接收端口的大小。
两种传输模式分别是:
采样模式和队列模式。
采样模式:
消息携带相同的但是更新的数据(messagestypicallycarrysimilar,butupdated,data)。
消息没有排队。
消息保留在源端口直到它被发送出去或被覆写。
当消息到达目的端口时,每个新消息覆盖前面的消息,该消息保留在目的端口直到它自己被覆写。
采样模式支持变长消息。
采样模式的刷新率(RefreshRate):
刷新率指明从消息被目的端口接收开始,一个有效性消息允许的最大可接受时间。
当创建端口时,指明该属性。
当消息被读取时,一个有效性输出参数用来指明是否接收消息的时间与端口的刷新率一致。
队列模式:
一个消息的每个新实例可以包含唯一的不同数据。
因此,在传输时不允许覆写前面的消息。
消息在源端口排队直到它们被发送,没有消息丢失(除了在一个带有RECEIVER_DISCARD的满消息队列的情况下)。
消息被存储在接收端口直到一个进程读取它们。
队列模式支持可变长度的消息。
2.4.4.端口
端口拥有下面几种类型:
●本地端口(LocalPorts)
本地端口是APEX端口,使得应用可以与同一VxWorks653模块上的应用进行通信。
本地端口被附加到模块上的分区上。
●伪端口(Pseudo-Ports)
伪端口可以用来在VxWorks653模块之外通信。
伪端口连接一个端口到驱动上。
●直接访问端口(Direct-AccessPorts)
直接访问端口实现了APEX队列端口而没有软件缓冲区。
它们也可以用来在VxWorks653模块之外通信。
拥有一个直接访问端口的通道必须有一个单源和一个单目的。
直接访问端口可以在分区或伪分区中。
●空端口
端口占位
端口的属性在XML配置文件中指明。
在运行时通过调用configRecordFieldGet()以及合适的参数,可以从核心操作系统获得相应的配置值。
2.4.5.队列消息函数
创建队列端口:
CREATE_QUEUING_PORT服务创建一个空的队列端口,并返回一个端口ID。
QUEUING_DISCIPLINE属性指定了阻塞的进程排队的方式是FIFO或基于优先级次序。
发送队列消息:
SEND_QUEUING_MESSAGE服务发送消息到指定的队列端口。
如果队列端口有充足的空间,则将消息加到端口队列的尾端。
如果没有充足的空间,则发送进程阻塞,并且将发送进程按照排队规则加入到发送进程的队列中。
进程在发送进程的队列中等待直到超时或者队列端口变得空闲。
接收队列消息:
RECEIVE_QUEUING_MESSAGE服务从指定队列端口接收消息。
如果队列端口不为空,则队列端口的头部消息被移除并返回给调用进程。
如果队列端口为空,则进程阻塞直到超时或者有消息到达。
获得队列端口信息:
GET_QUEUING_PORT_ID服务获得指定队列端口的端口ID。
GET_QUEUING_PORT_STATUS服务获得队列端口的状态信息,包括端口方向,在端口的消息数目,等待进程的数目,大小。
2.4.6.采样消息函数
创建采样端口:
CREATE_SAMPLING_PORT服务创建一个空的采样端口,并返回一个端口ID。
写采样消息:
WRITE_SAMPLING_MESSAGE服务写消息到一个指定的采样端口,覆写前面的消息。
读采样消息:
READ_SAMPLING_MESSAGE服务在指定的采样端口读取消息,并且返回一个合法性参数,用来指明是否消息的时间(age)同端口的刷新率一致。
消息的时间(age)是消息写入到端口到消息在目的端口被读取的时间之差。
得到采样端口信息:
GET_SAMPLING_PORT_ID服务获得指定采样端口的端口ID。
GET_SAMPLING_PORT_STATUS服务获得采样端口的状态信息,包括端口方向,刷新率,大小,在指定采样端口上次读取的消息的合法性。
2.5.分区内通信
APEX提供下列APEX对象使得分区内的进程能够相互通信。
●缓冲区
●黑板
●信号量
●事件
2.5.1.使用APEX缓冲区通信
APEX缓冲区使得分区内的进程可以互相通信。
通信是不直接的:
进程间通过缓冲区通信而不直接通信。
缓冲区在消息队列中存储多个消息。
创建APEX缓冲区:
APEX缓冲区仅仅当分区被初始化时(除NORMAL模式以外)被创建。
进程可以创建尽可能多的缓冲区,只要提前分配给分区缓冲区的内存能够支持创建这些缓冲区。
CREATE_BUFFER服务创建了一个空的缓冲区,带有名字、最大消息数目、最大消息大小以及等待进程的队列规则(FIFO或PRIORITY)。
服务返回一个缓冲区ID。
发送消息给APEX缓冲区:
SEND_BUFFER服务发送消息给一个指定的缓冲区。
如果缓冲区为空,那么消息按照FIFO规则存储在缓冲区的消息队列中,如果此时有进程正在等待接收消息,那么从接收进程等待队列中取出第一个进程,并且置该进程为就绪状态。
如果缓冲区为满,则发送进程阻塞,处于等待状态,并且将发送进程按照队列规则放入到发送进程等待队列,并指定一个超时值。
如果服务超时,则返回TIMED_OUT。
从APEX缓冲区接收消息:
RECEIVE_BUFFER服务从一个指定的缓冲区接收消息。
如果缓冲区不空,那么消息从缓冲区的FIFO消息队列中移除;如果缓冲区为满并且有进程正在等待发送消息,那么消息从缓冲区的FIFO消息队列中移除,将等待发送进程队列中的第一个发送进程移出队列,并置于就绪状态。
如果缓冲区为空,则接收进程进入等待状态,并且按照队列规则放入到等待接收进程队列中,并指定一个超时值。
如果服务超时,则返回TIMED_OUT。
获得APEX缓冲区信息:
GET_BUFFER_ID服务获得指定缓冲区的缓冲区ID。
GET_BUFFER_STATUS服务获得指定缓冲区的信息,包括当前消息数目,等待进程数目,最大可允许的消息数目,最大可允许的消息大小。
2.5.2.使用APEX黑板通信
APEX黑板支持一个分区内的进程间通信。
通信是不直接的:
进程间通过缓冲区通信而不直接通信。
创建黑板:
APEX黑板仅仅当分区被初始化时(除NORMAL模式以外)被创建。
进程可以创建尽可能多的黑板,只要提前分配给分区黑板的内存能够支持创建这些黑板。
CREATE_BLACKBOARD服务创建了一个空黑板,包括名字、最大消息数目信息,服务返回一个黑板ID。
展示黑板消息:
DISPLAY_BLACKBOARD服务写一个消息到黑板上,并从等待进程队列中移除所有的等待进程,并置于它们到就绪态。
消息仍然保留在黑板上。
读黑板消息:
如果指定黑板不空,则READ_BLACKBOARD从黑板上读取消息。
如果黑板为空,则读消息进程被置为等待状态,并且指定一个超时值。
如果服务超时,则返回TIMED_OUT。
清除黑板:
CLEAR_BLACKBOARD服务从指定黑板清除消息,结果黑板变空。
得到黑板信息:
GET_BLACKBOARD_ID服务获得指定黑板的ID。
GET_BLACKBOARD_STATUS服务获得指定黑板的信息,包括状态(EMPTY或者OCCUPIED),等待消息的数目,允许的最大消息大小。
黑板的状态变迁:
2.5.3.使用APEX信号量通信
APEX信号量是计数信号量。
进程等待信号量来获得访问资源的权利,当进程访问完资源后释放信号量。
信号量的当前值表明当前能够获取该信号量的次数。
创建APEX信号量:
APEX信号量仅仅当分区被初始化时(除NORMAL模式以外)被创建。
进程可以创建尽可能多的信号量,只要提前分配给分区信号量的内存能够支持创建这些信号量。
CREATE_SEMAPHORE服务创建了一个信号量,包含名字,最大值,当前值,排队规则(FIFO或PRIORITY),服务返回一个信号量ID。
等待APEX信号量:
如果指定的信号量的当前值不为零,那么WAIT_SEMAPHORE服务减少这个当前值,进程继续运行。
如果当前值为零,那么进程被放入到等待状态,并且根据信号量的排队规则进行排队,并指定了一段超时值,如果服务超时,返回TIMED_OUT。
释放(Signalling)APEX信号量: