您的位置:首页 > 其它

uC/OS-II消息队列及操作

2013-04-09 14:21 169 查看
使用消息队列可在任务之间传递多条消息,消息队列由三部分组成:事件控制块、消息队列和消息。



事件控件块成员OSEventPtr指向一个叫做队列控制块(OS_Q)的结构,该结构管理着一个数组MsgTb1[],该数组中的元素都是指向消息的指针。

[b][b]一. 消息队列的操作

[/b][/b]
1. 创建消息队列

OS_EVENT  *OSQCreate (void **start, INT16U size);
start为存放消息缓冲区指针数组的地址;size为该数组的大小;函数的返回值为消息队列的指针。

2. 请求消息队列

void  *OSQPend (OS_EVENT *pevent, INT16U timeout, INT8U *err);
也就是从消息队列中取消息,返回值为消息指针,也就是MsgTb1[]中的内容。

3. 向消息队列发送消息

//以FIFO(先进先出)的方式组织消息队列
INT8U  OSQPost (OS_EVENT *pevent, void *msg);

//以LIFO(后进先出)的方式组织消息队列
INT8U  OSQPostFront (OS_EVENT *pevent, void *msg);

也就是往MsgTb1[]中添加数据。

4. 清空消息队列

INT8U  OSQFlush (OS_EVENT *pevent);
5. 删除消息队列

OS_EVENT  *OSQDel (OS_EVENT *pevent, INT8U opt, INT8U *err);

[b][b]二. 例子

[/b][/b]
//主要往消息队列中发消息
void  StartTask(void *pdata)
{
    OSStatInit();             /* 初始化ucos的统计任务 */
        OSTaskCreate(MyTask,
                (void*)0,
                &MyTaskStk[TASK_STK_SIZE - 1],
                3);

        OSTaskCreate(YouTask,
                (void*)0,
                &YouTaskStk[TASK_STK_SIZE - 1],
                4);
    
    s = "How many times can receive this string?";
    
    OSQPostFront(Str_Q, s);    //send message LIFO
                
    for (;;)
    {
          if(OSTimeGet()>100 && OSTimeGet()<500)
          {
              s100 = "Now, OSTime value between 100 to 500";
              OSQPostFront(Str_Q, s100);                        //send message
              
              s = "Which Task receive this string?";
              OSQPostFront(Str_Q, s);                                //send message
                      
          }
          
          if(OSTimeGet()>5000 && OSTimeGet()<5500)
          {
              s500 = "Now, OSTime value between 5000 to 5500";
              OSQPostFront(Str_Q, s500);                        //send message
          }

         OSTimeDlyHMSM(0,0,1,0); /* 等待1S */
    }
}

//从消息队列中取消息
void  MyTask(void *pdata)
{
    for (;;)
    {
        PC_DispStr(0, ++y,"MyTask", DISP_BGND_BLACK+DISP_FGND_WHITE);
        
        ss = OSQPend(Str_Q, 0, &err); //request message queue
                    
        PC_DispStr(10,y, ss,DISP_BGND_BLACK+DISP_FGND_WHITE);
        
        OSTimeDlyHMSM(0,0,1,0); /* 等待1s */
    }
}

//从消息队列中取消息
void  YouTask(void *pdata)
{
    for (;;)
    {
        PC_DispStr(0, ++y,"YouTask", DISP_BGND_BLACK+DISP_FGND_WHITE);
        
        ss = OSQPend(Str_Q, 0, &err);//request message queue    
            
        PC_DispStr(10, y, ss, DISP_BGND_BLACK+DISP_FGND_WHITE);

            OSTimeDlyHMSM(0,0,1,0); /* 等待1s */
        
    }
}

这个例子是:StartTask往消息队列里发数据,而MyTask、YouTask不停的从队列中取数据。

现象如下:



从现象可以看出:

1. 在MyTask取出How many times can receive this string? 后,MyTask和YouTask都处于了等待状态。

2. 一段时间后(OSTime >5000),来数据了,MyTask先获得了数据。

3. 当数据取完后,MyTask和YouTask还是都处于了等待状态。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: