Vxworks 多任务之间的通信

实验要求:设计两个任务tServer和tClient,tClient负责通知tServer处理共享内存中的数据,为数据增加头部信息(可以用一句话模拟)。共享内存要用互斥信号量来保护,通知采用消息队列发送,tServer收到通知后需要给tClient反馈确认消息,如果tClient在一定时间内收不到确认消息,将重发通知,最大重传次数为3。

实验目的:熟悉VxWorks进程间通信机制,并通过实验了解信号量、消息队列、定时器机制的使用方法,掌握基本的通信程序编写。


实验要求:将实验二的程序改成网络通信程序,安装Tornado ULIP仿真网卡驱动,启动2个vxSim目标系统,其中一个vxSim为Client,另一个为Server。Server与Client通过socket API进行数据的收发。Client将内存中的数据发送给Server,Server收到通知后需要给Client反馈确认消息,如果Client在一定时间内收不到确认消息,将重发通知,最大重传次数为3。
实验要求:1、最基本要求是能够完成数据收发。
2、socket可以使用TCP也可以使用UDP
3、具体通信内容及方式不限,可以自由发挥,可以扩展成稍微复杂的协议通信。
实验目的:熟悉Tornado ULIP仿真网卡驱动的安装和使用;熟悉VxWorks bootable工程的创建和VxWorks映像的生成;熟悉VxWorks网络编程。

1 个回答

通常,在一个实时系统中,存在着多个并发的任务来协同实现系统的功能,操作系统必须为这些任务提供快速且功能强大的通信机制。在VxWorks系统中,有信号量(semaphore)、消息队列(message queue)、管道(pipe)、事件(event)等通信机制,对一个系统开发人员来说,如何合理地使用这些通信机制,是系统能够长期高效、可靠、安全运行的关键。
1、 信号量(semaphore)
  在VxWorks种,信号量是提供任务间同步和互斥的最快速、开销最小的机制,VxWorks有三种不同类型的信号量:
 (1) 二进制信号量:可用于2个任务之间的同步工作。如任务A必须在任务B完成特定的动作以后才能进行,在这种情况下,任务A可以获取信号量而处于阻塞(pend)状态,任务B在完成特定的动作后释放该信号量。一般来说二进制信号量适用于一对一的任务之间的同步。
 (2) 互斥信号量:主要用于任务之间共享数据区的互斥保护,具有优先级反转、安全删除、递归等特性。在有2个或2个以上的任务共享一个数据区的时候,必须使用互斥机制进行保护。
 (3) 计数器信号量:类似于二进制信号量,但是对信号量的释放、获取有计数功能,而二进制信号量则只有0和1两种状态。
  VxWorks提供了一组管理信号量的函数接口供开发者使用,包括创建、删除、获取、释放等。
虽然信号量具有快速、开销小的优点,但也有它的局限性,首先它无法提供额外的信息,其次对于一个任务必须与多个任务进行同步的情况,信号量也无能为力。因此在许多场合,信号量必须与其它通信机制配合使用来完成任务之间的通信。
2、 消息队列(message queue)
  消息队列是VxWorks提供的单个CPU中的任务之间通信的主要机制之一。消息队列允许基于FIFO或基于任务优先级方式排队消息,一个消息队列的消息数目和消息长度可以由开发者在创建消息队列时指定。在理论上,VxWorks允许多个任务向同一个消息队列发送消息,或者从同一个消息队列接收消息;而在实际应用中,一般来说只有一个任务从消息队列接收消息,有一个或多个任务发送消息,即这个消息队列有多个生产者,而只有一个消费者。消息队列时单向的,对于需要进行双向通信的两个任务,必须使用两个消息队列。消息队列非常适合于Client-Server结构的任务之间的通信,如图一,任务Client1和Client2都需要任务Server的服务,它们通过消息队列“Request Queue”向任务Server发送请求和参数,任务Server处理请求后分别通过“Reqpy Queue 1”和“Reqpy Queue 2”向这两个任务返回结果。
在VxWorks中,消息队列是一种代价比较高的一种通信机制,因此在使用时应该使消息的长度尽量短,而且应避免在需要十分频繁通信的场合使用消息队列。另外消息队列中的消息是排队的,即使是完全相同的消息,后面的消息也不会覆盖前面的消息。
3、管道(pipe)
  在VxWorks中,管道是一种通过虚拟的I/O设备来实现的消息队列通信机制。使用函数pipeDevCreate()和pipeDevDelete()来生成和删除管道,管道一经生成后,任务之间就可以使用标准I/O操作主要是read()和write()进行通信。管道的优点在于它是一个I/O设备,与标准的VxWorks I/O一样,可以使用select机制,而有了select机制,一个任务很方便地使用多个异步I/O设备,如任务要处理同时从串口、管道、socket接收到的数据,就可以使用select。
4、事件(event)
  在5.5版本之前,VxWorks并没有事件这一通信机制。事件(event) 最早出现在pSOS实时操作系统中,在风河公司收购了pSOS之后,从VxWorks 5.5之后,加入了事件机制,并在pSOS事件的基础上做了增强和改进。事件可用于任务和中断服务程序ISR之间、任务和任务之间、任务和VxWorks资源之间进行通信。任务用函数eventReceive()来接收它关心的事件,用eventSend()来向另一个任务发送事件。
  VxWorks资源主要是指信号量和消息队列,一个任务要想从VxWorks资源接收到事件,必须先进行注册(register),那么当资源处于FREE状态时,会向注册过的任务发送一个事件。对于每一个VxWorks资源,最多只允许有一个任务注册。如对于消息队列,任务可以使用函数msgQEvStart()来进行注册,那么当有消息到达这个消息队列而又没有任务等待这个消息队列时,会向这个任务发送一个事件,表明消息队列可用。而对于信号量,可以用函数semEvStart()来进行注册。但必须注意的是,一个任务接收到资源发送的事件后,并不能保证这个任务能获取该资源,如获取信号量、从消息队列接收到消息。
  在VxWorks中,每一个任务都有一个32位事件寄存器,其中高8位由VxWorks系统保留,开发者可以使用低24位,其每一位表示一种事件,而事件的意义则完全有任务来定义,因此对于不同的任务,相同的位可能有不同的意义。而VxWorks并不对事件进行计数,而只表示该事件发生过,这与消息队列不同,因此接收事件的任务并不能知道接受到的事件发生的次数。
事件非常适合于一个任务必须与多个任务进行通信的场合,如任务A必须同时与任务B、任务C、任务D进行通信,其中任务B通过消息队列向任务A发送数据,其发送频率较低,它要求任务A必须及时进行处理;而任务C则只是向任务A指示一种状态,但频率很高;而任务D用来通知任务A释放动态申请的资源,并停止运行。在这种场合,事件机制能很好地解决问题。

你的回答