ucos-ii学习笔记——消息队列的原理及使用

ucos-ii学习笔记——消息队列的原理及使用

(2012-10-07 17:32:29)
转载
标签:

ucos-ii

操作系统

程序设计

嵌入式

分类:学习探讨
 

ucos-ii学习笔记——消息队列的原理及使用

 

Created on: 2012-10-7

      Author: zhang bin

 

学习笔记

for ucos-ii  PC

redesigned by zhang bin

2012-10-7

versionsV-0.1

All Rights Reserved

 

 

 

#include "includes.h"

 

#define  TASK_STK_SIZE                 512       

#define  N_MESSAGES                    128       

 

OS_STK        StartTaskStk[TASK_STK_SIZE];

OS_STK        MyTaskStk[TASK_STK_SIZE];

OS_STK        YouTaskStk[TASK_STK_SIZE];

 

char *s_flag;   //该字符串指示哪个任务在运行

//char *s_1;  

 

char          *ss;  //存放接收到的消息指针

 

char          *s100; //存放发送消息的指针

char          *s;

char          *s500;

void          *MsgGrp[N_MESSAGES];    //定义消息指针数组

//创建消息队列,首先需要定义一个指针数组(用于存放消息邮箱),然后把各个消息数据缓冲区的首地址存入这个数组中

//最后再调用函数OSQCreate()来创建消息队列

 

INT8U         err;

INT8U         y=0;

 

OS_EVENT      *Str_Q;                //定义事件控制块指针 队列的事件控制块指针 用于存放创建的消息队列的指针

 

void  MyTask(void *data);                     

void  StartTask(void *data);       

void  YouTask(void *data); 

 

 

 

void  main (void)

{

    OSInit();                                              

    PC_DOSSaveReturn();                                    

    PC_VectSet(uCOS, OSCtxSw);                             

    

Str_Q=OSQCreate(&MsgGrp[0],N_MESSAGES);                //创建消息队列

//函数的第一个参数&MsgGrp[0]void **start,是存放消息缓冲区指针数组的地址,它是指向指针数组的指针

//可以用指针数组的首个元素的地址表示

//N_MESSAGES是该数组的大小

//返回值是消息队列的指针   Str_QOS_EVENT型的指针,是事件控制块型的指针

 

    OSTaskCreate(StartTask, (void *)0, &StartTaskStk[TASK_STK_SIZE - 1], 0);

    OSStart();                                             

}

 

 

 

void  StartTask (void *pdata)

{

#if OS_CRITICAL_METHOD == 3                                

    OS_CPU_SR  cpu_sr;

#endif

 

    INT16S     key;

 

    pdata = pdata;     

 

    OS_ENTER_CRITICAL();

    PC_VectSet(0x08, OSTickISR);                           

    PC_SetTickRate(OS_TICKS_PER_SEC);                      

    OS_EXIT_CRITICAL();

    OSStatInit();                                          

    

    OSTaskCreate(MyTask, (void *)0, &MyTaskStk[TASK_STK_SIZE - 1], 3);

    OSTaskCreate(YouTask, (void *)0, &YouTaskStk[TASK_STK_SIZE - 1], 4);

    

   // s="How many strings could be geted";

    //OSQPostFront(Str_Q,s);      //发送消息 以LIFO后进先出的方式发送

    //第一个参数Str_Q是消息队列的指针,是OSQCreate的返回值,第二个参数s是消息指针

    

    for (;;) 

    {

     s_flag="The StartTask is running!";

     PC_DispStr(50,++y, s_flag, DISP_FGND_RED + DISP_BGND_LIGHT_GRAY);   //提示哪个任务在运行

    

        if(OSTimeGet()>100&&OSTimeGet()<500)

        {

         s100="The value of OSTIME is from 100 to 500 NOW!!";

         OSQPostFront(Str_Q,s100);   //发送消息 以LIFO后进先出的方式发送

         //发送消息 以LIFO后进先出的方式发送

           //第一个参数Str_Q是消息队列的指针,是OSQCreate的返回值,第二个参数s是消息指针

         s="The string belongs to which task."

         OSQPostFront(Str_Q,s);      //发送消息 以LIFO方式发送  所以如果要申请消息时,会先得到s,然后才是s100

        }

 

if(OSTimeGet()>1000&&OSTimeGet()<1500)

        {

         s500="The value of OSTIME is from 1000 to 1500 NOW!!";

         OSQPostFront(Str_Q,s500);   //发送消息

        }

        

        if (PC_GetKey(&key) == TRUE)   

        {                   

            if (key == 0x1B) 

            {          

                PC_DOSReturn();          

            }

        }

 

        OSTimeDlyHMSM(0, 0, 1, 0);        

    }

}

 

 

 

void  MyTask(void *pdata)

{

#if OS_CRITICAL_METHOD == 3                                

    OS_CPU_SR  cpu_sr;

#endif

    pdata=pdata;

    for (;;)

    {             

     s_flag="The MyTask is running!";

     PC_DispStr(50,++y, s_flag, DISP_FGND_RED + DISP_BGND_LIGHT_GRAY);   //提示哪个任务在运行

    

     ss=OSQPend(Str_Q,0,&err);    //请求消息队列,参数分别是:Str_Q为所请求消息队列的指针  第二个参数为等待时间

     //0表示无限等待,&err为错误信息,返回值为队列控制块OS_Q成员OSQOut指向的消息(如果队列中有消息可用的话),如果

     //没有消息可用,在使调用OSQPend的任务挂起,使之处于等待状态,并引发一次任务调度

     //因为前面发送消息时使用的是LIFO的方式,所以此处第一次得到的消息是上面最后发送的消息

    

     PC_DispStr(3,y, ss, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);  //显示得到的消息

     //s_1="M";

     PC_DispStr(0,y,"My",DISP_FGND_RED + DISP_BGND_LIGHT_GRAY);  //显示是哪一个任务显示的

    

     OSTimeDlyHMSM(0, 0, 1, 0);  

    }

}

 

void  YouTask(void *pdata)

{

#if OS_CRITICAL_METHOD == 3                                

    OS_CPU_SR  cpu_sr;

#endif

    pdata=pdata;

    for (;;)

    {             

     s_flag="The YouTask is running!";

     PC_DispStr(50,++y, s_flag, DISP_FGND_RED + DISP_BGND_LIGHT_GRAY);   //提示哪个任务在运行

    

     ss=OSQPend(Str_Q,0,&err);    //请求消息队列

    

     PC_DispStr(3,y, ss, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);  //显示得到的消息

     //s_1="Y";

     PC_DispStr(0,y,"You",DISP_FGND_RED + DISP_BGND_LIGHT_GRAY);  //显示是哪一个任务显示的

    

     OSTimeDlyHMSM(0, 0, 1, 0);  

    }

}

 

//运行的现象说明上面分析是正确的,因为当时钟节拍数大于100,小于500时,会发送第一个if语句中的两个字符串s100s

//下面运行的任务接收到并且显示。当时钟节拍数大于1000小于1500时,发送第二个if语句中的字符串,下面运行的任务

//接收并显示。当时钟节拍数大于1500时,就不再发送消息了,下面的任务得不到消息就无限等待下去,所以就不再显示了

//从运行的现象不难可以看出,有时MyTaskYouTask运行了,但是没有得到消息而处于等待状态

//使用上面的方法可以很清楚地看出任务调度和运行的关系了 MyTaskYouTask 是交替运行的,因为延迟时间相等

你可能感兴趣的:(ucos-ii学习笔记——消息队列的原理及使用)