VxWorks操作系统中的信号量类型
. 互斥信号量
基本行为与二进制信号量一致,不同之处如下:
仅用于互斥;
仅能由提取它(即调用())的任务释放;
不能在中断服务程序中释放;
()函数操作非法;
.. 优先级倒置:互斥信号量选项能够继承优先级算法,优先级继承协议确保在资源阻塞的所有任务中优先级最高的且拥有资源执 行资格的任务将优先执行。一旦任务的优先级被提高,它以提高后的优先级执行;直到释放其占有的全部互斥信号量后,该任务将返回到正常或者标准的优先级。该 选项要求与优先级队列()一起使用。
.. 删除安全:一个受信号量保护的临界区域内经常需要保护执行任务避免被意外地删除。删除一个在临界区执行的任务可能会导致意想不到的后果。原语 ()和()提供了一种任务安全的方法。但是在使用互斥信号量选项时,每次使用 ()将隐含调用(),使用()将隐含调用()。使用这种方式,任务在占用信号量时不会 被删除。
.. 递归资源访问:互斥信号量能够递归获得。在释放信号量前,递归获取的互斥信号量被释放和提取的次数应该相等,这通过一个计数器跟踪实现。
. 计数器信号量
是实现任务同步和互斥的另一种手段,适用于保护多份复制的资源。
(3)消息队列
在操作系统里,单个CPU里任务间的主要通信方式使用消息队列。
------------------------------------------------------------------------------------
| 调用 | 描述 |
|() |分配并初始化一个消息队列 |
|() |终止并释放一个消息队列 |
|() |向一个消息队列发送消息 |
|() | 从一个消息队列接收消息 |
------------------------------------------------------------------------------------
消息的优先级:和
中断服务程序能够向消息管道中写入,但不能从消息管道中读取。
(4)管道
管道使用操作系统中的I/O系统,并提供替换消息队列的接口。管道是由驱动程序管理的虚拟I/O设备,任务能够使用标准I/O 对管道进行打开、读取或写入等操作,另外也可以调用函数ioctl。
与消息管道类似,中断服务程序能够向管道写入,但不能从管道读取。
(5)任务间网络通信
套接字
远程程序调用RPC
(6)信号
支持软件信号功能。信号可以异步改变任务的控制流程。任何任 务或中断服务程序可以向指定任务发送信号。接收到信号的任务立即挂起当前的执行线程,在下次调度执行时转而执行指定的信号处理程序。信号处理程序在接收任 务的上下文中执行,并使用任务的堆栈。即使在任务被阻塞时,仍可调用信号处理程序。
通常信号处理程序可作为中断处理程序看待,任何导致调用程序阻塞的函数均不能在信号处理程序中调用。
Wind内核支持两种类型的信号接口:UNIX BSD风格的信号和POSIX兼容信号。为了简化设计,建议在一个应用程序中使用一种类型接口,不要混合使用不同接口。
基本信号函数:
----------------------------------------------------------------------------------------------------------
| POSIX 1003.1b兼容调用|UNIX BSD兼容调用| 描述 |
| () | () | 指定信号的处理程序 |
| kill() | kill() | 向任务发送信号 |
| raise() | N/A | 向自身发送信号 |
| () |() | 检查或设置信号的处理程序 |
| () | pause() | 挂起任务直至任务提交 |
| () | N/A| 恢复一组用于传递而被阻塞的信号|
| () -------| ------------------------ | ---------------------------------------------|
| () -------| | |
| ()--------| ()| 设置信号屏蔽 |
| ()-------- | | |
|() ------- |--------------------- ---|---------------------------------------------|
| () | ()| 设置阻塞信号的屏蔽 |
| () | () | 增加到一组阻塞的信号中 |
----------------------------------------------------------------------------------------------------------
信号发生通常与硬件中断相联系。例如总线出错、非法指令以及浮点数异常都可能产生某种信号。
3.事件
事件是一种在任务和中断处理程序间,或任务和结构体间的通信方式。在事件上下文中,这些结构体被用作为资源,包括信号量和消息队列。只有任务能够接收事件;然而任务、中断处理程序或资源都可以发送事件。
(1)事件pSOS
. 发送和接收事件
任务、中断服务程序以及资源都使用同一个应用编程接口()来发送事件。
对于从资源接收事件的任务来说,任务必须用资源寄存,而且请求资源在空闲时发送一系列指定的事件;这种资源可以使信号量,也可以是消息队列。
. 等待事件
任务能够从一个或多个资源等待多个事件。每个资源可以发送多个事件,同样任务也可以等待接收一个或多个事件。
. 事件的寄存
从资源接收事件时,资源只能寄存一个任务。如果另一个任务随后用同样的资源寄存,那么不会通知原先寄存的任务就自动解除原有的寄存。事件寄存的处理与pPOS事件则不同。
. 空闲资源
当资源给任务发送事件表明空闲时,不意味着资源的空闲状态可以保留。因此,从资源等待事件的任务在资源空闲时被解除阻塞;但同时资源也可能被取走。
对于两个或两个以上的任务持续交换资源所有权的情况,资源虽然被释放,但并不处于空闲状态,所以资源将不会发送事件。
. 应用编程接口
------------------------------------------------------------------------------------------------
|函数| 描述 |
| () | 给任务发送事件 |
| () | 等待事件 |
| () | 寄存一个被信号量告知可用的任务 |
| () | 寄存一个被消息队列告知有消息到来的任务 |
| | 寄存一个被可变长度的消息队列告知有消息到来的任务 |
------------------------------------------------------------------------------------------------
(2)事件
事件执行以pPOS事件为基石。
. 空闲资源定义
互斥信号量:当一个互斥信号量被释放并且在其上没有任务阻塞
二进制信号量:当没有任务占有或等待一个二进制信号量
计数器信号量:一个计数器信号量在其计数值非零且其上没有阻塞任务时
消息队列:队列中有消息存在,且没有等待该队列中消息而阻塞的任务
. 对pPOS事件的扩展
单任务资源寄存:在pPOS系统中一个任务用资源寄存发送pSOS事件时,它会无意地取消另一个已用该资源寄存的任务寄存,第一个用该资源寄存的任务将无 限期地被阻止。事件则提供了一个选项,在该选项中如果另一个任务已经用某个资源寄存了,则不允许第二个任务用该资源再寄存。如果第二个任务 用该资源寄存,将返回一个错误。
立即发送选项:当一个pPOS任务用资源寄存时,即使寄存时资源处于空闲状态,也不会立即给任务发送时间。对于事件,默认行为与之相同。然 而,事件提供了一个选项,即若该资源在寄存时处于空闲状态,该选项允许任务请求资源立即给其发送事件。
自动取消寄存选项:pPOS执行过程序要任务在从资源接收任务后明确地取消寄存。执行提供一个选项,该选项可以通知资源仅发送一次事件,然后在发送后自动取消寄存。
自动解除资源堵塞:当删除资源(一个信号量或者消息队列时),调用函数()和()解除所有任务的挂起。在任务等待 被删除资源发送事件时,该措施保护任务避免无限期地堵塞。然后任务继续执行,导致任务挂起的函数()返回一个ERROR值。
事件25到32(或到或)用作系统保留用,用户不可以使用这些事件。
(3)比较API
------------------------------------------------------------------------------------------------------------------
|函数|pPOS函数| 注释 |
| | |直接端口 |
| | | 直接端口 |
| | |中的新功能 |
| | |等价于用非零事件参数调用 |
| | |等价于用事件参数为0调用 |
| | |等价于用非零事件参数调用 |
| | |等价于用事件参数为0调用 |
| | |没有一个固定长度的消息队列机制 |
------------------------------------------------------------------------------------------------------------------
4.看门狗定时器
包括一个看门狗定时器机制,允许任何C函数与一个特定的时间 延时器联系。看门狗定时器作为系统时钟中断服务程序的一部分来维护。被看门狗定时器调用的函数通常作为系统时钟中断级的中断服务代码来执行。但如果内核由 于某种原因不能立即执行能够函数(例如一个优先中断或者内核状态),函数将放在工作队列中。工作队列中的函数以 (通常是0)优先级来执行。
-------------------------------------------------------------------------------------------
| 调用 | 描述 |
|() |分配并初始化一个看门狗定时器 |
|() |终止并释放一个看门狗定时器 |
|()|启动一个看门狗定时器 |
|() |取消当前的一个计数的看门狗定时器 |
-------------------------------------------------------------------------------------------
5.中断服务代码
为了尽快地响应中断,中断处理程序在所有任务上下文之外的一个特殊上下文内执行。因此,中断处理不涉及到任务上下文的切换。
--------------------------------------------------------------------------------------------
| 调用 | 描述 |
|() | 设置中断处理的C程序 |
|() | 如果是从中断级调用,返回真 |
|() | 获得当前中断嵌套深度 |
|() | 设置处理器的中断屏蔽级 |
|() | 禁止中断 |
|() | 重新允许中断 |
|()| 设置向量基地址 |
|()| 得到向量基地址 |
|() | 设置异常向量 |
|() | 获得异常向量 |
--------------------------------------------------------------------------------------------
调用中断服务程序函数存在着很多的限制。例如,在应用中断服务程序时不能使用(), ()和()函数,但是可以使用(), (), ()和bcopy()这样的函数。
产生这些限制的原因是由于中断服务程序不在一个固定的任务上下文中执行,而且没有任务控制块,因此所有中断服务程序必须共享一个单独的堆栈。
. 中断服务程序基本限制为禁止调用导致调用者堵塞的函数。
. ()和free()都要求获得信号量,中断服务程序不能调用任何用于创建或删除的函数。
. 中断服务程序不能通过驱动程序来执行I/O操作,因为大多数的设备驱动器可能会堵塞等待设备的调用者,因此它们需要一个任务上下文。但管道驱动器是个例外,它设计用于中断服务程序的写操作。
. 提供了一个记录功能,允许向系统任务平台打印文本信息。这个机制是专门为中断服务程序使用而设计的,同时它也是从中断服务程序打印信息的最常用方法。
. 中断服务程序同时禁止调用浮点协处理器函数。在操作系统中,由()函数建立的中断驱动代码不能保存和恢复浮点寄存器。若中断服务程序需要使用浮点指令,则必须明确地保存和恢复中函数浮点协处理器的寄存器。
. 所有函数库,像连接链和环形缓冲器,都可以被中断服务程序使用。