新聞中心

        EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > ucos-ii學習筆記——消息隊列的原理及使用

        ucos-ii學習筆記——消息隊列的原理及使用

        作者: 時間:2016-11-28 來源:網(wǎng)絡 收藏
        Createdon:2012-10-7

        Author:zhangbin

        本文引用地址:http://www.104case.com/article/201611/322851.htm

        學習筆記

        forucos-iiPC

        redesignedbyzhangbin

        2012-10-7

        versions:V-0.1

        AllRightsReserved

        #include"includes.h"

        #defineTASK_STK_SIZE512

        #defineN_MESSAGES128

        OS_STKStartTaskStk[TASK_STK_SIZE];

        OS_STKMyTaskStk[TASK_STK_SIZE];

        OS_STKYouTaskStk[TASK_STK_SIZE];

        char*s_flag;//該字符串指示哪個任務在運行

        //char*s_1;

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

        char*s100;//存放發(fā)送消息的指針

        char*s;

        char*s500;

        void*MsgGrp[N_MESSAGES];//定義消息指針數(shù)組

        //創(chuàng)建消息隊列,首先需要定義一個指針數(shù)組(用于存放消息郵箱),然后把各個消息數(shù)據(jù)緩沖區(qū)的首地址存入這個數(shù)組中

        //最后再調(diào)用函數(shù)OSQCreate()來創(chuàng)建消息隊列

        INT8Uerr;

        INT8Uy=0;

        OS_EVENT*Str_Q;//定義事件控制塊指針隊列的事件控制塊指針用于存放創(chuàng)建的消息隊列的指針

        voidMyTask(void*data);

        voidStartTask(void*data);

        voidYouTask(void*data);

        voidmain(void)

        {

        OSInit();

        PC_DOSSaveReturn();

        PC_VectSet(uCOS,OSCtxSw);

        Str_Q=OSQCreate(&MsgGrp[0],N_MESSAGES);//創(chuàng)建消息隊列

        //函數(shù)的第一個參數(shù)&MsgGrp[0]是void**start,是存放消息緩沖區(qū)指針數(shù)組的地址,它是指向指針數(shù)組的指針

        //可以用指針數(shù)組的首個元素的地址表示

        //N_MESSAGES是該數(shù)組的大小

        //返回值是消息隊列的指針Str_Q是OS_EVENT型的指針,是事件控制塊型的指針

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

        OSStart();

        }

        voidStartTask(void*pdata)

        {

        #ifOS_CRITICAL_METHOD==3

        OS_CPU_SRcpu_sr;

        #endif

        INT16Skey;

        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="Howmanystringscouldbegeted?";

        //OSQPostFront(Str_Q,s);//發(fā)送消息以LIFO后進先出的方式發(fā)送

        //第一個參數(shù)Str_Q是消息隊列的指針,是OSQCreate的返回值,第二個參數(shù)s是消息指針

        for(;;)

        {

        s_flag="TheStartTaskisrunning!";

        PC_DispStr(50,++y,s_flag,DISP_FGND_RED+DISP_BGND_LIGHT_GRAY);//提示哪個任務在運行

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

        {

        s100="ThevalueofOSTIMEisfrom100to500NOW!!";

        OSQPostFront(Str_Q,s100);//發(fā)送消息以LIFO后進先出的方式發(fā)送

        //發(fā)送消息以LIFO后進先出的方式發(fā)送

        //第一個參數(shù)Str_Q是消息隊列的指針,是OSQCreate的返回值,第二個參數(shù)s是消息指針

        s="Thestringbelongstowhichtask.";

        OSQPostFront(Str_Q,s);//發(fā)送消息以LIFO方式發(fā)送所以如果要申請消息時,會先得到s,然后才是s100

        }

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

        {

        s500="ThevalueofOSTIMEisfrom1000to1500NOW!!";

        OSQPostFront(Str_Q,s500);//發(fā)送消息

        }

        if(PC_GetKey(&key)==TRUE)

        {

        if(key==0x1B)

        {

        PC_DOSReturn();

        }

        }

        OSTimeDlyHMSM(0,0,1,0);

        }

        }

        voidMyTask(void*pdata)

        {

        #ifOS_CRITICAL_METHOD==3

        OS_CPU_SRcpu_sr;

        #endif

        pdata=pdata;

        for(;;)

        {

        s_flag="TheMyTaskisrunning!";

        PC_DispStr(50,++y,s_flag,DISP_FGND_RED+DISP_BGND_LIGHT_GRAY);//提示哪個任務在運行

        ss=OSQPend(Str_Q,0,&err);//請求消息隊列,參數(shù)分別是:Str_Q為所請求消息隊列的指針第二個參數(shù)為等待時間

        //0表示無限等待,&err為錯誤信息,返回值為隊列控制塊OS_Q成員OSQOut指向的消息(如果隊列中有消息可用的話),如果

        //沒有消息可用,在使調(diào)用OSQPend的任務掛起,使之處于等待狀態(tài),并引發(fā)一次任務調(diào)度

        //因為前面發(fā)送消息時使用的是LIFO的方式,所以此處第一次得到的消息是上面最后發(fā)送的消息

        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);

        }

        }

        voidYouTask(void*pdata)

        {

        #ifOS_CRITICAL_METHOD==3

        OS_CPU_SRcpu_sr;

        #endif

        pdata=pdata;

        for(;;)

        {

        s_flag="TheYouTaskisrunning!";

        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);

        }

        }

        //運行的現(xiàn)象說明上面分析是正確的,因為當時鐘節(jié)拍數(shù)大于100,小于500時,會發(fā)送第一個if語句中的兩個字符串s100和s

        //下面運行的任務接收到并且顯示。當時鐘節(jié)拍數(shù)大于1000小于1500時,發(fā)送第二個if語句中的字符串,下面運行的任務

        //接收并顯示。當時鐘節(jié)拍數(shù)大于1500時,就不再發(fā)送消息了,下面的任務得不到消息就無限等待下去,所以就不再顯示了

        //從運行的現(xiàn)象不難可以看出,有時MyTask或YouTask運行了,但是沒有得到消息而處于等待狀態(tài)

        //使用上面的方法可以很清楚地看出任務調(diào)度和運行的關系了MyTask和YouTask是交替運行的,因為延遲時間相等



        評論


        相關推薦

        技術專區(qū)

        關閉
        主站蜘蛛池模板: 贡嘎县| 大渡口区| 昌图县| 道真| 诸暨市| 朝阳县| 同仁县| 遂溪县| 延庆县| 盐源县| 保德县| 石首市| 西畴县| 东丽区| 定南县| 金溪县| 鹤山市| 阳东县| 佛山市| 于都县| 明水县| 太原市| 棋牌| 黄大仙区| 巴里| 麻城市| 靖江市| 开江县| 玉环县| 扶风县| 白朗县| 田林县| 洪泽县| 砚山县| 临邑县| 宣威市| 北票市| 阳春市| 布拖县| 三河市| 浙江省|