新聞中心

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

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

        作者: 時間:2016-11-28 來源:網絡 收藏
        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;//存放發送消息的指針

        char*s;

        char*s500;

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

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

        //最后再調用函數OSQCreate()來創建消息隊列

        INT8Uerr;

        INT8Uy=0;

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

        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);//創建消息隊列

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

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

        //N_MESSAGES是該數組的大小

        //返回值是消息隊列的指針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);//發送消息以LIFO后進先出的方式發送

        //第一個參數Str_Q是消息隊列的指針,是OSQCreate的返回值,第二個參數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);//發送消息以LIFO后進先出的方式發送

        //發送消息以LIFO后進先出的方式發送

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

        s="Thestringbelongstowhichtask.";

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

        }

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

        {

        s500="ThevalueofOSTIMEisfrom1000to1500NOW!!";

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

        }

        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);//請求消息隊列,參數分別是: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);

        }

        }

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

        }

        }

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

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

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

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

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



        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 象州县| 海阳市| 荃湾区| 沧州市| 贵定县| 河南省| 察隅县| 丰县| 利川市| 鹤庆县| 吴桥县| 渭南市| 岚皋县| 清徐县| 任丘市| 时尚| 武山县| 武清区| 巩留县| 安康市| 荣昌县| 鄱阳县| 获嘉县| 乌拉特中旗| 漳平市| 东光县| 璧山县| 松原市| 云南省| 玉龙| 天长市| 二手房| 焦作市| 西和县| 枣强县| 盘山县| 绥滨县| 远安县| 古丈县| 赤壁市| 松潘县|