VX编程手册

更新时间:2023-12-05 00:44:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

VxWorks编程手册

编程手册

赵洪策

2003年3月7日

第 1 页 共 35 页

VxWorks编程手册

目录

编程手册 .......................................................................................................................................... 1

1.VxWorks任务 .................................................................................................................... 3

1.1VxWorks中的多任务 ................................................................................................. 3 1.2任务状态转换 ............................................................................................................. 3 1.3 任务的调度程序 ........................................................................................................ 4 1.4任务控制 ..................................................................................................................... 7 1.5任务扩展 ................................................................................................................... 10 1.6任务错误状态: ....................................................................................................... 11 1.7任务异常的处理 ....................................................................................................... 11 1.8共享代码和重载入 ................................................................................................... 11 1.9VxWorks系统任务 ................................................................................................... 13 1.10任务堆栈 ................................................................................................................. 13 2任务间通讯 .......................................................................................................................... 14

2.1共享内存结构 ........................................................................................................... 14 2.2互斥变量 ................................................................................................................... 14 2.3Semaphores信号量 ................................................................................................... 15 2.4消息队列 ................................................................................................................... 20 3、中断 ................................................................................................................................... 23 4、I/O系统 ............................................................................................................................ 25

4.1介绍 ........................................................................................................................... 25 4.2文件、设备和驱动 ................................................................................................... 26 4.3基本I/O .................................................................................................................... 26 4.4 Buffered I/O—Stdio .................................................................................................. 28 4.6异步输入、输出(AIO) ........................................................................................ 29 4.7 VxWorks中的设备 .................................................................................................. 30

4.7.1串口I/O设备(终端和伪终端设备) ......................................................... 30 4.7.2 PIPE设备 .................................................................................................... 31 4.7.3 伪内存设备 ................................................................................................. 32 4.7.4 网络文件系统设备 ..................................................................................... 32 4.7.5 非NFS设备 ................................................................................................ 32 4.7.6 block设备 ................................................................................................... 33 4.7.7 SOCKET...................................................................................................... 33 4.7.8 VxWorks与Host系统I/O的区别 ............................................................ 33

5. 本地文件系统 .................................................................................................................... 33

5.1介绍 ........................................................................................................................... 33 5.1dosFs .......................................................................................................................... 33 5.2 Raw File System: rawFs ............................................................................................ 33 5.3 CD-ROM File System: cdromFs ............................................................................... 34 5.4 目标服务器文件系统-TSFS ................................................................................... 35

第 2 页 共 35 页

VxWorks编程手册

前言 本手册主要描述VxWorks系统,VxWorks是高性能实时操作系统Tornado的组件。也描述了如何使用VxWorks工具开发实时应用程序。目前流行的实时系统都基于多任务和任务间通讯。多任务环境允许时实应用程序作为独立的任务构建,每个任务都有自己的执行程序和系统资源。任务间通讯允许这些任务为完成某一行为而同步和相互通讯。在VxWorks中,从信号量到消息队列,从管道到socket,都涉及任务间通讯。 在实时系统中,另一个重要工具是硬件中断处理,因为中断是通知外部事件系统的常用机制,为了得到对中断的更快响应,在VxWorks 中,interrupt service routines (ISRs)是一个独立的部分,不在任务之列。主要涉及如下几个主题:

1、 多任务 2、 任务间通讯 3、 中断处理 4、 I/O系统 5、 文件系统 1.VxWorks任务

在VxWorks中,任务,同调度程序一样,是工作的基本单元,与其他系统中的线程等同(threads)。所有的调度程序都发生在任务层。VxWorks的任务是相关联的,共享的大部分相同的系统资源。

1.1VxWorks中的多任务

多任务为应用程序提供了一个基本的机制,以控制和响应多个、离散的事件。每个任务都有自己的内容,包括CPU环境和系统资源,由内核按照一定的调度算法运行。在发生任务切换时,与任务相关的内容保存到task control block (TCB)中。任务的内容包括: -内存地址空间 -执行线程,即任务的程序计数器 -CPU寄存器和浮点寄存器 -动态变量和函数调用的堆栈 -标准输入、输出和错误的I/O分配 -延时定时器 -时间片定时器 -内核控制结构 -信号处理器

1.2任务状态转换

系统内核维护了当前每个任务的状态,应用程序调用内核函数,导致一个任务从一种状态转换到另一种状态。表1-1列出了任务的所有状态: 3 状态 READY PEND 描述 此任务状态只等待CPU资源,其他资源除外 此任务状态是由于一些资源不可用而被阻塞 第 3 页 共 35 页

VxWorks编程手册

DELAY SUSPEND 此任务状态是休眠一段时间 此任务状态是执行程序不可用,此状态主要用来调试,SUSPEND状态不影响状态的转换,只影响程序的执行。因此,pended-suspended任务一直不阻塞,而delayed-suspended tasks任务能够一直唤醒。 此任务状态是停止(暂停),当一个任务被debugger停止,通常是在任务中设置了断点。此状态不影响状态的转换,只影响程序的执行。 此任务状态是both delayed and suspended 此任务状态是 both pended and suspended 此任务状态是阻塞一段时间值 此任务状态是 both pended and stopped 此任务状态是 stopped with a timeout value 此任务状态是 both stopped and suspended 此任务状态是 both pended with a timeout value and suspended 此任务状态是 pended, stopped and suspended 此任务状态是 both stopped with a timeout value, and suspended. 此任务状态是 pended with a timeout value, stopped, and suspended 此任务状态是:状态由state指定,加上继承的优先级 BREAK DELAY + S PEND + S PEND + T PEND + BRK DLY + BRK BREAK + S PEND + S + T PEND + B + S BRK + S + T P + B + S +T state + I

PEND + B + T 此任务状态是 both pended with a timeout value, and stopped 任务可以在一到两步内创建并且激活,也可以调用函数taskSpawn( )一步生成(spawned,即创建又激活)。某些情况下,使用taskCreate( )和 taskActivate( )函数两个步骤是有用的,这允许应用程序在使用任务之前先创建(因为任务的创建要花费一部分taskSpawn( )时间),然后采用快速激活机制激活任务。在创建任务之后,激活之前,任务在suspended状态,激活时转换到ready状态。可以在任何状态下删除任务。

1.3 任务的调度程序

多任务需要一种调度机制,用来为ready状态的任务分配CPU。在wind中,缺省模式是基于优先级的抢占模式算法,但是你可以选择轮询模式。

1.3.1抢占式优先级模式

采用抢占式优先级算法,每个任务都有一个优先级,内核决定分配CPU给具有最高优先级的ready状态的任务。此方法既为抢占式,既当一个比当前任务有更高优先级的任务准备运行时,内核立即保存当前任务的相关内容,并切换到有更高优先级的任务。图1-2中,任务1被拥有更高优先级的任务2抢占,依次,又被任务3抢占。

第 4 页 共 35 页

VxWorks编程手册

ready——pend:semTake( ) / msgQReceive( ) ready——delay:taskDelay( )

ready——suspend:taskSuspend( )

pend——ready:semGive( ) / msgQSend( ) pend——suspend:taskSuspend( ) delay——ready:expired delay delay——suspend:taskSuspend( ) suspend——ready:taskActivate( ) suspend——pend:taskResume( ) suspend——delay:taskResume( ) 当任务3完成时,任务2继续执行,当任务2完成后,任务1继续执行。 表1-2,任务排列控制例程: Call kernelTimeSlice( ) taskPrioritySet( ) taskLock( ) taskUnlock( ) Description 控制轮询式调度程序 改变任务优先级 取消任务的再调度 允许任务的再调度 第 5 页 共 35 页

VxWorks编程手册

图1-2——优先级的抢占 wind内核有256个优先级级别,从0到255,优先级0最高,255最低。当创建任务式,需要设置其优先级,当任务在运行时,可以调用函数taskPrioritySet( )来改变优先级。

1.3.2轮询模式

抢占式的优先级模式可以通过增加轮询式进行扩充。轮询模式是所有具有相同优先级的ready任务平均分配CPU。如果不用轮询式,当多个具有相同优先级的任务共享CPU时,某个任务由于没有被阻塞可能独占整个CPU,因此其他等优先级的任务没有机会运行。 通过时间分片的方式,轮询模式可以实现为具有相同优先级的任务公平的分配CPU。每个任务(一个优先级组)运行一定的时间或时间片,然后另一个任务执行相同的时间。轮询模式可以通过调用函数kernelTimeSlice( )来触发,它的一个参数是时间片,再将处理器交给另一个等优先级任务之前的运行时间。 详细说来,每个任务都有一个运行时间计数器对应,每个时钟加1。当指定的时间片间隔完成时,计数器清0,当前任务被放到等优先级任务队列的最后,新的任务被执行,计数器被初始化为零。 如果一个任务在运行时被告优先级的任务抢占,那么运行时间计数器被保存,当此任务再次被运行时,时间计数被恢复。图1-3显示了具有相同优先级的任务t1、t2和t3的调度程序。

图1-3——轮询模式

任务2被任务4抢占,当任务4完成时,任务2从中断点恢复。

第 6 页 共 35 页

VxWorks编程手册

1.3.2抢占锁(Preemption Locks )

wind调度程序可以调用函数taskLock( )和taskUnlock( )来取消和使能每个任务的抢占模式。当调用函数taskLock( )取消某个任务的调度程序时,这个任务不会被抢占。然而,如果此任务已被阻塞或悬挂,调度程序就选择高优先级的适合的任务运行。当被锁定的任务解锁,并再次运行时,抢占模式再次被取消。(When the preemption-locked task unblocks and begins running again, preemption is again disabled.)

注意,抢占锁阻止任务内容被切换,但不能锁定中断处理。抢占锁也能用来实现互斥操作。

1.4任务控制

下面粗略浏览一下VxWorks的任务程序,在VxWorks的库taskLib中可以找到。这个程序提供了任务创建和控制的方法。

任务创建:

下表的函数用来创建任务: Call taskSpawn( ) taskCreate( ) taskActivate( ) Description 生成(创建和激活)一个新任务 创建一个新任务,但不激活它。 激活一个已经创建的任务 函数taskSpawn( )的参数有:新建任务名(ASCII字符串)、优先级、选项字、堆栈大小、主程序地址及10个参数(作为启动参数传给主函数): id = taskSpawn ( name, priority, options, stacksize, main, arg1, …arg10 );

此函数生成任务内容,包括分配堆栈、配置任务环境,新任务在制定程序的入口开始执行。另外,此函数包括底层的创建和激活步骤(taskCreate( )和 taskActivate( ))。

任务名称和IDs: 当创建任务时,你可以制定任意长度的ASCII字符串作为任务名称。VxWorks返回任务Ids,ID是4字节长度,多数VxWorks任务都把任务ID作为任务的唯一标示。VxWorks用0任务ID表示正在调用的任务。VxWorks不需要任务名称是唯一的,但是推荐使用唯一任务名,以免混淆。而且,为了更好的利用Tornado开发环境,任务名称不应与全局函数和变量名称发生冲突。为了避免名字冲突,VxWorks是用约定前缀pdt开头。你可能不想为你的任务命名,如果它是NULL,taskSpawn( )函数的name参数就用指针替代,VxWorks为其分配唯一的名称,形式为pdtN,N为十进制整数。 通常,任务名可以转化为对应的任务Ids,以简化任务间的交互。 taskLib中的例程管理任务IDs和任务名称: 函数: Call taskName( ) taskNameToId( ) taskIdSelf( ) taskIdVerify( ) Description 得到任务id对应的任务名称 得到任务名称对应的任务id 得到调用任务的id(正在运行的) 验证一个指定任务是否存在 第 7 页 共 35 页

VxWorks编程手册

下表的函数也用于任务名称和任务Ids: Description 找到与名称字符串和类型相匹配的对象 得到对象名称 设置对象名称 显示已知名称的对象的相关信息 Routine objNameToId( ) objNameGet( ) objNameSet( ) objNameShow( ) objNameToId( ) 函数是VxWorks的缺省函数,为了包括objNameShow( )函数,配置INCLUDE_OBJECT_NAME_SHOW组件。

任务和对象的所有权: 同其他的wind对象一样,任务也有所有者。但是同其他对象相比,任务的缺省所有者是任务所生成的保护域(protection domain)。在创建任务时,可以指定参数,以使这些任务成为他们所创建的其他对象的所有者,但是,与其他对象不同,任务的所有者不可以被改变。 使用函数objOwnerGet( )可以得到对象拥有者的id。函数objShowAll( )可以用来得到对象所有权的层次关系。

任务选项:

当生成任务时,可以根据需要,执行与操作,来指明选项参数,如下表所示(如果任务执行浮点操作,VX_FP_TASK选项必须被设置): 选项 VX_USER_MODE VX_SUPERVISOR_MODE VX_UNBREAKABLE VX_FP_TASK VX_PRIVATE_ENV VX_NO_STACK_FILL VX_STDIO_INHERIT 值(hex) 描述 0x0000 0x0001 0x0002 0x0008 0x0080 0x0100 0x0200 在用户模式下执行,这是所有任务的缺省模式(除了内河任务), 等同于VX_SUPERVISOR_MODE选项设置为not。 在超级用户模式下运行。这是内核任务的缺省模式。 不允许在调试时对任务设置断点 执行浮点计算 包括私有环境支持,见envLib. 调用函数checkStack() 时努允许填充0xee 当任务用此选项创建时,任务继承VX_STDIO_INHERIT选项以及标准I/O文件描述符。当不使用此选项时,被创建的任务使用标准I/O文件描述符,可以用函数pdStdIoSet( )来改变。 被任务创建的对象直接由此任务所有,而不是任务的主保护域。例外是任务本身,他一直都由保护域所有。 取消任务的堆栈溢出保护 VX_TASK_OBJ_OWNER 0x0400 VX_NO_STACK_OVERFLOW 0x0800 例子:

为了创建浮点操作的任务,如下:

tid = taskSpawn (\2387, 0, 0, 0, 0, 0, 0, 0, 0, 0);

第 8 页 共 35 页

VxWorks编程手册

任务选项值可以在任务创建之后进行检测和修改,可以使用如下函数(目前,只有VX_UNBREAKABLE、VX_TASK_OBJ_OWNER和VX_STDIO_INHERIT选项可以被改变): 函数 taskOptionsGet( ) taskOptionsSet( ) 描述 检测任务参数 设置任务选项

任务信息:

任务的信息可以通过调用下列函数得到,任务的状态信息是动态的,信息可能不是当前的,除非此任务是在休眠状态: 函数 taskIdListGet( ) taskInfoGet( ) taskPriorityGet( ) taskRegsGet( ) taskRegsSet( ) taskIsSuspended( ) taskIsReady( ) taskTcb( ) 描述 将所有活动状态的任务id填写到个数组中 得到一个任务的信息 检查任务的优先级 检查一个任务的寄存器(但是不能被当前任务使用) 设置一个任务的寄存器(但是不能被当前任务使用) 检查一个任务是否在悬挂状态(suspended.) 检查一个任务是否准备运行就绪 得到一个任务的控制块的指针,此函数只用于内核保护域。 任务的删除、资源回收和安全删除: 任务可以从系统中动态删除,下列函数用于对任务的删除: 函数 exit( ) taskDelete( ) taskSafe() taskUnsafe( ) 描述 结束正在运行任务,释放内存* 结束制定的任务,释放内存* 保护当前任务,防止被删除 取消taskSafe( )操作,即能够删除当前任务 说明:*当任务结束时,此任务所分配的内存并不释放;但是,当主保护域删除时,内存才被释放。

警告:不要在不恰当的时候删除任务。在应用程序删除一个任务时,此任务应该释放所有资源。 当入口函数(创建任务时指定的)返回时,意味着已经隐式的调用了函数exit( )。一个任务可以调用函数taskDelete( )来杀死本身或其他任务。因此,一个任务可以通过调用exit(),或调用taskDelete( )函数,或在入口函数中返回,来删除任务本身。 当一个任务被删除时,其他任务不会知道,函数taskSafe( ) 和taskUnsafe( )防止任务的意外删除。taskSafe( )函数防止一个任务被其他任务删除,例子: 当一个任务获得信号量,并正访问某些数据结构,当执行到某个关键域,此任务被删除了,那么数据结构可能处于一种混乱状态,信号量也没有被任务释放,关键的资源对其他任务是不可用的。

第 9 页 共 35 页

VxWorks编程手册

当一个任务试图删除另一个被保护的任务时会处于阻塞状态,当另一个任务完成操作后会调用taskUnsafe( )函数解除保护,那么此任务就可以被删除了。为了支持嵌入式的安全删除,一个计数器纪录taskSafe( )和taskUnsafe( )函数被调用的次数,只有当计数器为0时(即unsafes和safes次数一样多),才允许删除。保护操作只用于当前任务。 下面是一个例子: taskSafe ();

semTake (semId, WAIT_FOREVER); /* Block until semaphore available */ .

. critical region .

semGive (semId); /* Release semaphore */ taskUnsafe ();

如上例所示,安全删除通常与互斥量成对出现。

任务控制: 任务控制函数如下: 函数 taskSuspend( ) taskResume( ) taskRestart( ) taskDelay( ) nanosleep( ) 描述 Suspend a task. Resume a task. Restart a task. Delay a task; delay units are ticks, resolution in ticks. Delay a task; delay units are nanoseconds, resolution in ticks. VxWorks调试工具需要程序悬挂、恢复任务,用来冻结任务的状态以便检测。 当任务在执行过程中可能遇到灾难性的徐徐错误,因此任务必须能够重新启动。taskRestart( )函数的重启机制是重新创建任务,其参数与第一次创建任务的参数相同。 Delay操作是任务能够休眠一段时间,常用来检测(polling)应用程序,例如,让任务休眠半个时钟周期:taskDelay (sysClkRateGet ( ) / 2); sysClkRateGet( )函数返回系统时钟的速率,每秒的ticks数。你也可以用nanosleep()函数(POSIX)实现同样的功能,只是时间单位不同,nanosleep()函数以秒为单位。Delay操作的另一个影响是此任务被排到同优先级任务序列之后。因此,你能把CPU给另一个同优先级任务,只要你延迟0个ticks: taskDelay (NO_WAIT); /* allow other tasks of same priority to run */ 0延迟只能用于taskDelay( )函数; nanosleep( )函数会出错。

1.5任务扩展

VxWorks提供一些钩子函数,可以在任务创建、任务切换及任务删除时调用。(任何被钩子函数调用的用户程序必须是在内核域),当调用钩子函数时,应注意一点:

1、 Task switch hook routines must not assume any VM context is current other than the

kernel context (as with ISRs).

2、 Task switch and swap hooks must not rely on knowledge of the current task or invoke

any function that relies on this information; for example, taskIdSelf( ). 3、 A switch or swap hook must not rely on the TASK_ID_VERIFY(pOldTcb) mechanism

to determine if the delete hook, if any, has already executed for the self-destructing task

第 10 页 共 35 页

VxWorks编程手册

信号量的控制: Wind信号量提供了统一的信号量控制接口,不分类型,只有创建函数需要指明类型。 函数 semBCreate( ) semMCreate( ) semCCreate( ) semDelete( ) semTake( ) semGive( ) semFlush( ) 描述 分配和初始化一个二进制信号量 分配和初始化一个互斥信号量 分配和初始化一个计数信号量 删除并释放信号量 启动信号量 停止信号量 Unblock all tasks that are waiting for a semaphore. 函数semBCreate( ), semMCreate( ), 和 semCCreate()返回信号量ID,当创建信号量时,需要指定队列类型,信号量可以按照优先级顺序或先入先出顺序加入队列中。 当删除信号量时,即调用函数semDelete( ) 时,一定要注意不要删除另一个任务一直正在请求的信号量。

二进制信号量: 获取一个信号量的流程:

二进制信号量可以被看作一个标志位(可用-FULL,不可用-empty),当一个任务起用一个二进制信号量,其结果取决于次信号量当前是否可用,如果可用(full),信号量立即变为不可用(empty),任务继续运行;如果不可用,任务被加入到阻塞任务队列中,并等待信号量可用。

当任务停止信号量(调用函数semGive( )),其结果也取决于次信号量当前是否可用,如果信号量已经可用,停止信号量,结果没什么影响;如果信号量不可用,也没有任务等待获取它,那么信号量变为可用;如果信号量不可用,并且有多个任务正等待获取它,那么阻塞任务队列中的第一个任务变为非阻塞,信号量变为不可用。

释放一个信号量的流程:

第 16 页 共 35 页

VxWorks编程手册

互斥: 二进制信号量对共享资源的互锁访问是十分有效的,它将互斥操作的范围限制到只与它相关的资源。当一个任务想访问某些资源时,它必须首先获得信号量,只要一个任务保持此信号量,其他试图访问此资源的任务被阻塞;当任务完成了资源访问,并释放了信号量,才允许其他任务访问此资源。 因此,所有对资源的互斥访问都是使用semTake( )和semGive( )对。 3 semTake (semMutex, WAIT_FOREVER); .

. critical region, only accessible by a single task at a time .

semGive (semMutex);

同步信号: 当用于任务同步时,信号量可以代表一个任务正在等待的条件或事件。初始化时,信号量是不可用的,一个任务或ISR通过释放信号量代表事件的发生,另一个任务调用函数semTake( )等待信号量。等待的任务阻塞,直到事件发生和信号量被释放。 互斥信号和同步信号的区别是他们的顺序:对于互斥信号,信号量在初始化时是可用的,每个任务必须首先获取它,然后再释放他;对于同步信号,信号量在初始化时是不可用的,一个任务等待获取另一个任务释放的信号量。

互斥信号量: 互斥信号量的行为与二进制信号量基本相同,以定位互斥操作的内部问题,如优先级转换、安全删除、递归访问等:

1、 他只能用于互斥操作;

2、 他只能有获取它的任务释放; 3、 他不能从ISR处释放; 4、 semFlush()操作无效。

优先级反转: 当一个高优先级的任务被迫等待一个低优先级任务不确定的完成时间时,优先级发生了倒置问题。例子:

第 17 页 共 35 页

VxWorks编程手册

T1、T2、T3分别代表优先级为高、中、低的三个任务。任务T3获得了二进制信号量,并可以访问一些资源。当T1(也需要获得同一个信号量)抢占T3,以访问资源时,任务T1就会阻塞。如果T3正常完成资源的访问,T1不会有问题。但是,当中优先级的任务T2抢占了T3任务,这将妨碍T3放弃资源的访问,这种情况一直僵持着,T1将无限期的阻塞。

图——优先级倒置问题

互斥信号量有一选项——SEM_INVERSION_SAFE,它使用priority-inheritance算法,此协议保证访问某一资源的任务以最高优先级任务(也阻塞在这一资源)的优先级别执行。一旦此任务的优先级被提升,它就保持此优先级,直到此任务获取的所有互斥信号量被释放,然后此任务又恢复到正常的或标准的优先级。这样就防止了中优先级的任务的抢占。此选项必须与优先级队列一起使用(SEM_Q_PRIORITY)。 此方法不一定都可行。如果一个任务获取了几个不同的互斥信号量,其中的一个时任务的优先级别提升了,那么任务优先级将一直保持着,直到所有的信号量被释放。

图——优先级继承

在上图中,当T1阻塞在信号量时,通过把T3的优先级提升到与T1相同的优先级,就解决了优先级倒置问题,这种方法叫做优先级继承。他保护了T3,也就间接的保护了T1不被任务T2抢占。

下面是使用优先级继承算法创建互斥信号量的例子: semId = semMCreate (SEM_Q_PRIORITY | SEM_INVERSION_SAFE);

安全删除: 互斥信号量解决的另一个问题是任务删除。当信号量保护着关键域时,删除一个运行在关键域的任务是灾难性的。函数taskSafe( ) 和 taskUnsafe( )为任务删除提供了安全的解决方

第 18 页 共 35 页

VxWorks编程手册

案。而互斥信号量提供SEM_DELETE_SAFE选项,即每个semTake( )函数暗含着调用

taskSafe( )函数,每个semGive( )函数暗含着调用taskUnsafe( )函数。这样,拥有信号量的任务不能被删除。

例子:semId = semMCreate (SEM_Q_FIFO | SEM_DELETE_SAFE);

回归资源访问: 互斥信号量能够被回归的获取,即一个任务在施放信号量之前,可以多次获取信号量。但是,在释放回归获取的互斥信号量之前,信号量也必须获取同样次数,即semTake( )和semGive( )函数必须成对出现。 据个例子:

#include \#include \SEM_ID mySem;

/* Create a mutual-exclusion semaphore. */ init () {

mySem = semMCreate (SEM_Q_PRIORITY); }

funcA () {

semTake (mySem, WAIT_FOREVER);

printf (\...

funcB (); ...

semGive (mySem);

printf (\}

funcB () {

semTake (mySem, WAIT_FOREVER);

printf (\...

semGive (mySem);

printf (\}

计数信号量: 计数信号量是实现任务同步和互斥操作的另一种方式。与二进制信号量相似,只是多了一个计数器,记录信号量被释放的次数。信号量被释放一次,计数器加1;被获取一次,减1;当计数为0时,企图获取此信号量的任务将阻塞。 下表是一个例子: 信号量调用函数 调用后的计数 第 19 页 共 35 页

VxWorks编程手册

semCCreate( ) semTake( ) semTake( ) semTake( ) semTake( ) semGive( ) semGive( ) 3 2 1 0 0 0 1 Semaphore initialized with initial count of 3. Semaphore taken. Semaphore taken. Semaphore taken. Task blocks waiting for semaphore to be available. Task waiting is given semaphore. No task waiting for semaphore; count incremented. 特殊信号量选项: wind信号量接口包括两个特殊的选项,对于POSIX兼容的信号量则没有: 1、超时时间: 当一个任务阻塞等待信号量可用时,信号量获取操作可能需要限制到一定时间内,如果在这段时间内没有信号量被获取,则此操作失败。这个操作由函数semTake( )的一个参数控制,这个参数指明等待时间。如果在指定时间内获得了信号量,返回OK,否则返回ERROR,同时rrno被设置。参数NO_WAIT (0)表示不需要等待,WAIT_FOREVER (-1)表示一直等待。 2、队列: wind信号量为阻塞任务提供了信号量队列选择机制,包括基于先进先出(FIFO)和优先级两种机制。在创建信号量时就选择了队列类型。如使用了优先级继承选项(SEM_INVERSION_SAFE),就必须选择优先级机制。

POSIX信号量: POSIX定义有名字和无名字两种信号量,他们有相同的属性,但接口的使用稍微有些不同(见semPxLib)。POSIX中的术语wait(或lock)和post(或unlock)分别对应于VxWorks中的take和give。POSIX信号量是计数信号量。

2.4消息队列

当前的实时应用都是由一组相互独立又相互协作的任务组成。信号量为任务间同步和互锁提供了高效的机制,而在VxWorks中,消息队列是单处理器中主要的任务间通讯机制。消息队列允许不定数量、不定长度的消息排队等待。任何任务或ISR都能发送消息到消息队列,任何任务也能从消息队列中接受消息。多个任务可以从一个消息队列中接受或发送消息。两个任务间的全双工通讯通常需要两个队列,一个用于发,一个用于收。

第 20 页 共 35 页

本文来源:https://www.bwwdw.com/article/53bt.html

Top