您的位置:首页 > 其它

WRTOS系统消息队列的使用

2010-03-27 20:46 393 查看
  消息在操作系统中是个特殊的名词,更多的时候它指的是一种对象,而并非字面意义上的消息,可以泛指一切对象或数据结构。任务与任务之间的通讯或者数据传递在操作系统看来都是消息,操作系统提供了这样一种消息机制来满足不同的任务之间进行通讯。

  消息也是联系两个互不相关联互无关系的任务的载体,任务间通讯,也产生消息等等。

  WRTOS提供了消息服务,具体有点对点消息服务、同步信号量消息服务、消息队列服务,这里将介绍WRTOS中消息队列的使用。

  WRTOS4.0中改进了消息队列的系统服务,但压缩了消息队列的体积,由值传递方式改动成为指针传递,这样传递的效率会大大提高,同时消息内容可以是任何对象。WRTOS中消息被处理于队列结构中,出于安全性考虑,这个消息队列工作于非循环模式下,当队列满时,将产生消息丢失,但是确保证了以前的消息不被抹掉,任务应即时处理当前消息,消息的写入方式却是循环方式的,消息出队方式按时间先后顺序。

  假设有两个任务,任务A和任务B,任务B接收任务A发送的消息,并处理消息。为了使示例更加有通用性,我先定义如下消息结构:

  
typedef struct
{
  uint8 EventType;    //按键方式
  uint8 EventValue;    //按键值
  uint8 EventTime;       //按键持续时间
}KeyMsg;


  上面定义了一个键盘的消息类型,一则按键消息由三个参数组成,下面将用此消息为例在任务A与任务B相使用消息:

  
//Author: 愿陪你一生  QQ380052073
//Note: 任务A,不断向任务B发送0-9按键按下消息
void TaskA()
{
  Wrtos_QueryMessage CurMsg;
  KeyMsg MyMsg;
uint8 i=0;
  while(1){
  MyMsg.EventType=Wrtos_Key_PressDown;                     //生成按键按下的消息
 MyMsg.EventValue=i;
    MyMsg.EventTime=0;
    Wrtos_TaskPutQmsg(TaskB_ID,Wrtos_MsgType_KeyBoard,1,&MyMsg);       //向任务B发送消息
    i++;
if(i==10)i=0;                                  //反复生成0-9的按键消息
    Wrtos_TaskDelay(1000);                             //任务休眠1000系统节拍
}


  任务A中定义了一由本地消息MyMsg,并定义了一则系统消息CurMsg,任务A将本地消息填充为从0-9不断变化的按键KeyBoard按下消息,同时调用系统队列消息服务发送消息方法Wrtos_TaskPutQmsg(……)向任务B发出,这一系统调用的原型和使用方法为:

  
//WRTOS系统调用 向任务发送消息
Wrtos_TaskPutQmsg(uint8 Index,uint8 MsgType,uint16 MsgSize,void * Qmsg);
//Index:    目标任务优先及或任务ID
//MsgType:  消息类型
//MsgSize:  消息指针所指向的缓冲区中消息长度
//*Qmsg:  消息指针,指向消息位置


  任务A发送消息类型为Wrtos_MsgType_KeyBoard类型,即健盘消息,长度为1。之后任务A休眠1000系统节拍,周而复始,下面看看任务B的接收处理和编程方法:

  
//Author: 愿陪你一生  QQ380052073
//Note: 任务B等待健盘消息
void TaskB()
{
  Wrtos_QueryMessage MsgBuffer[5],*CurMsg;
  KeyMsg *MyMsg;
  uint8 i;
  Wrtos_TaskCreateQmsg(MsgBuffer,5);                 //向系统注册本地消息队列
while(1){
    CurMsg=Wrtos_TaskGetQmsg();                   //等待消息
    if(CurMsg>0){                                          //过滤空消息
      if(CurMsg->MsgType == Wrtos_MsgType_KeyBoard){     //判断是否按键消息
         MyMsg=(KeyMsg *)CurMsg->Qmsg;                 //从将消息内容格式化为按键消息
         switch(MyMsg->EventValue)                     //判断按键值
         {
            case  0:                                 //处理按键0按下
break;
case 1:                                  //处理按键1按下
break;
……                                       ……
case 9:                                  //处理按键9按下
break;

         }
      }
    }
  }
}


  上面代码示例了任务B如何接收任务A发送的消息,以及如何提取和处理消息。首先任务B在本地建立了长度为5的消息队列,最多可容纳5则消息,同时定义了按键消息指针,用于格式化消息内容,这点很重要,因为消息是任何对象,在使用消息时必须先将其拥有确定的类型,否则无法正确处理消息。任务B向系统注册了本地消息队列,这样本地消息接收队列便可以为系统参于管理,系统将会按队列方式依次将收到的消息放入这个本地队列中,其调用原型为:

  
//WRTOS 创建消自队列,注册到系统调用
Wrtos_TaskCreateQmsg(Wrtos_QueryMessage *MsgAddr,uint8 MsgLenth)
//*MsgAddr 消息队列地址
//MsgLenth 队列长度


  向系统注册消息队列后,系统便参于其管理,包括消息自动入队出队操作,循环操作,队列满阻塞操作等等,任务B随后进入消息等待状态,其系统调用为Wrtos_Task_GetQmsg();以下是调用原型:

  
//WRTOS等待消息调用
Wrtos_QueryMessage * Wrtos_TaskGetQmsg();


  任务进入等待消息状态后,系统将任务强制到休眠状态,当消息到来时,系统将消息进行入队操作,同时等待任务进入就绪态,产生系统任务切换,并使消息出队返回。任务B收消息后判断其是否为空消息,然后判断其消息类型,是否为自己所期待的消息类型,本处假设任务B也在等待键盘消息,则将其格式化为键盘消息,随即处理该消息。

  以上是WRTOS中消息队列的用法,借用键盘消息实例,可以看到其一般的调用和处理过程。当然还可以挂载任何形式的消息。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: