用uc/OS-II实现系统的消息循环

今天,做了uc/OS-II系统的消息循环的实验,写一些收获。

先说说消息机制的原理。通过消息循环可以实现基于时间驱动的应用程序,即每一个事件都会产生特定的消息,然后这个消息被发送到某个/某些任务消息队列中,任务读取到消息后作出相应的处理。任务消息队列一般采用FIFO结构,即最先发送的消息任务会最先读取到。

用uc/OS实现的系统消息循环感觉类似windows编程的消息机制。系统不断轮询来从消息队列中取出最近的消息进行处理。当然,用uc/OS实现的消息机制就要比windows的简单多了。在uc/OS中,通信机制里面有一种就是消息队列,通过这种通信方式我们就能在uc/OS中实现我们的消息机制。

在uc/OS中,消息队列可以工作与一对一的工作方式,即一个任务发送消息到消息队列,而另一个任务从消息队列中读取消息。这种方式简单也常用。另外还有一种多对一的工作方式,即多个任务发送消息队列到同一个消息队列,而另外只有一个任务从这个消息队列中读取信息,这种即是我们实现消息机制需要用到的工作方式。当然,消息队列还有其他工作方式,但是都不常用。

我们把消息队列作为任务消息队列,然后任务就可以通过读取消息队列中的消息来获取消息。当然,一般哪个任务需要处理消息循环才会建立相应自己的任务消息队列。消息的储存需要空间,所以还需要定义一个数组来进行消息的储存。因为消息的类型不同,所以数组的类型为void。而将任务队列与任务消息队列存储区连接起来的关键就是OS_EVENT  *OSQCreate (void **start, INT16U size)消息队列创建函数。任务消息的队列创建需在启动uc/OS之前。

实验中用到的关于消息函数已经有现成的了。在任务消息头文件中,我们可以自定义消息。

如:

#define TM_KEY 5762

       #define TM_KEYDOWN 5763

......

定义好消息结构体

typedef struct tagMSG

   uint32  message; // 消息值
    uint32  wParam; // 消息附加信息1
    uint32  lParam; // 消息附加信息2
} MSG;


然后是最重要的两个消息函数SendMessage()和GetMessage()。

  /****************************************************************************
* 名称:SendMessage()
* 功能:发送一个消息,即消息发送管理器。
*      根据实际情况,将消息分派到不同的任务消息队列中。
* 入口参数:msg 所要发送的消息(指针)
* 出口参数:操作成功返回TRUE,否则返回FALSE。
****************************************************************************/
uint8  SendMessage(MSG *msg)
{  
uint32  message;
   TMQ   *target;
   uint8   err;


   message = msg->message;
   switch(message)
   {  
   case  TM_KEY:
case  TM_KEYDOWN:
 
 case  TM_KEYUP:
    target = task_tmq; // 若是键盘消息,向task1_tmq任务消息队列发送
     break;
     
   case  TM_UART0RCV:
      target = task_tmq; // 若是串口接收消息,向task1_tmq任务消息队列发送
      break;
     
      // (在此添加用户任务消息分派处理)
      
   default:  target = NULL;
      break;
   }
   err = OSQPost(target, msg);
   if(err==OS_NO_ERR) 
    return(TRUE);
   else  
    return(FALSE); 
}

/****************************************************************************
* 名称:GetMessage()
* 功能:等待一个消息。当接收到消息时才返回。
* 入口参数:tmq 等待的任务消息队列(指针)
* 出口参数:返回接收到的消息。
****************************************************************************/
MSG  *GetMessage(TMQ *tmq)
{  

uint8  err;
return(OSQPend(tmq, 0, &err));
}

具体实现的代码就不用写了,重要是这个思想和实现方法。

你可能感兴趣的:(编程,工作,windows,struct,OS,任务)