新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > ucos-ii學習筆記——信號量集(事件標志組)的原理及使用

        ucos-ii學習筆記——信號量集(事件標志組)的原理及使用

        作者: 時間:2016-11-28 來源:網絡 收藏
        Createdon:2012-10-8

        Author:zhangbin

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

        學習筆記

        forucos-iiPC

        redesignedbyzhangbin

        2012-10-8

        versions:V-0.1

        AllRightsReserved

        #include"INCLUDES.h"

        #defineTASK_STK_SIZE512

        OS_STKStartTaskStk[TASK_STK_SIZE];//起始任務

        OS_STKMyTaskStk[TASK_STK_SIZE];

        OS_STKYouTaskStk[TASK_STK_SIZE];

        OS_STKHerTaskStk[TASK_STK_SIZE];

        char*s1="Mytaskisrunning";

        char*s2="Youtaskisrunning";

        char*s3="Hertaskisrunning";

        INT8Uerr;//返回的錯誤信息

        INT8Uy=0;//字符顯示位置

        OS_FLAG_GRP*Sem_F;//定義一個信號量集指針,是標志組類型,OS_FLAG_GRP類型的指針用標志組描述信號量

        //事件控制塊用來描述信號量,消息郵箱,消息隊列

        voidStartTask(void*data);

        voidMyTask(void*data);

        voidYouTask(void*data);

        voidHerTask(void*data);

        voidmain(void)

        {

        OSInit();

        PC_DOSSaveReturn();

        PC_VectSet(uCOS,OSCtxSw);

        Sem_F=OSFlagCreate(0,&err);//創建信號量集函數的原型為:OS_FLAG_GRP*OSFlagCreate(OS_FLAGSflags,INT8U*err)

        //其中參數OS_FLAGSflags是信號的初始值,在這里指定為0,即信號初始值為0.參數*err是錯誤信息,前面已經定義了

        //INT8Uerr;//返回的錯誤信息,所以此處為&err

        //返回值為OS_FLAG_GRP型的指針,即為創建的信號量集的標志組的指針,

        //前面已經定義了OS_FLAG_GRP*Sem_F;//定義一個信號量集指針

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

        OSTaskCreate(HerTask,(void*)0,&HerTaskStk[TASK_STK_SIZE-1],5);

        for(;;){

        //如果恩下ESC鍵,則退出UC/OS-II

        if(PC_GetKey(&key)==TRUE){

        if(key==0x1B){

        PC_DOSReturn();

        }

        }

        OSTimeDlyHMSM(0,0,3,0);

        }

        }

        voidMyTask(void*pdata)

        {

        #ifOS_CRITICAL_METHOD==3

        OS_CPU_SRcpu_sr;

        #endif

        pdata=pdata;

        for(;;)

        {

        OSFlagPend(//請求信號量集

        Sem_F,//請求信號量集指針

        (OS_FLAGS)3,//過濾器請求第0和第1位信號0011這里是把數據3強制轉化為OS_FLAGS類型的數據,

        //因為過濾器和信號量集中的信號都是OS_FLAGS類型的數據

        //OS_FLAG_WAIT_SET_ALL+OS_FLAG_CONSUME,//信號全是1表示信號有效參數OS_FLAG_CONSUME表示當

        //任務等待的事件發生后,清除相應的事件標志位

        OS_FLAG_WAIT_SET_ALL,//信號全是1表示信號有效沒有加參數OS_FLAG_CONSUME,所以不會清除標志位

        0,//等待時限,0表示無限等待

        &err//錯誤信息

        );

        //任務MyTask在這里請求信號量集,如果請求到了信號量集,就繼續運行,下面就顯示信息,如果請求不到信號量集

        //MyTask就掛起,處于等待狀態,只到請求到了信號量集才繼續往下運行

        PC_DispStr(10,++y,s1,DISP_BGND_BLACK+DISP_FGND_WHITE);//顯示信息

        OSTimeDlyHMSM(0,0,2,0);//等待2s

        }

        }

        voidYouTask(void*pdata)

        {

        #ifOS_CRITICAL_METHOD==3

        OS_CPU_SRcpu_sr;

        #endif

        pdata=pdata;

        for(;;)

        {

        PC_DispStr(10,++y,s2,DISP_BGND_BLACK+DISP_FGND_WHITE);//顯示信息

        OSTimeDlyHMSM(0,0,8,0);//等待8s

        OSFlagPost(//向信號量集發信號

        Sem_F,//發送信號量集的指針

        (OS_FLAGS)2,//選擇要發送的信號給第1位發信號0010同樣把2強制轉化為OS_FLAGS型的數據,

        //因為信號為OS_FLAGS型的

        OS_FLAG_SET,//信號有效的選項信號置1OS_FLAG_SET為置1OS_FLAG_CLR為置0

        &err//錯誤信息

        );

        OSTimeDlyHMSM(0,0,2,0);//等待2s

        }

        }

        voidHerTask(void*pdata)

        {

        #ifOS_CRITICAL_METHOD==3

        OS_CPU_SRcpu_sr;

        #endif

        pdata=pdata;

        for(;;)

        {

        PC_DispStr(10,++y,s3,DISP_BGND_BLACK+DISP_FGND_WHITE);//顯示信息

        OSTimeDlyHMSM(0,0,8,0);//等待8s

        OSFlagPost(//向信號量集發信號

        Sem_F,

        (OS_FLAGS)1,//給第0位發信號0001,把1強制轉化為OS_FLAGS型的

        OS_FLAG_SET,//信號置1

        &err

        );

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

        }

        }

        //因為任務MyTask請求信號量集的時候請求的是第一位和第零位,所以下面兩個任務分別發送第一位和第零位信號

        //有一個問題:任務請求信號量集,得到信號后,信號量集中的對應的信號會被清除么??從本例的運行現象來看,好像

        //是沒有清除,因為當第一次YouTask和HerTask運行后,間隔了8s任務MyTask才運行,因為YouTask和HerTask都等待了8s

        //才向信號量集發送信號。這個顯現是正常的。但是以后MyTask每間隔2s就運行一次,沒有間隔8s,等待信號量集。

        //查到了:OSFlagPend()函數允許指定在任務等待的事件發生后,重新置起或是清除相應的事件標志位。這是通過在調用

        //OSFlagPend()函數時將一個常量OS_FLAG_CONSUME和參數wait_type相“加”(或者相“或”)來實現的。

        //例如希望等待事件標志組的BIT0位置位,而此時事件標志組的BIT0位已經置位了,那么如果在調用OSFlagPend()時,把參數

        //wait_type加上OS_FLAG_CONSUME,就能清除這個事件標志位。如下所示:(詳細說明,參見P210)



        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 鲜城| 上虞市| 平顺县| 永修县| 宜阳县| 尼勒克县| 塘沽区| 上杭县| 仁怀市| 大城县| 兰坪| 科技| 禄劝| 景宁| 加查县| 观塘区| 昌吉市| 荔波县| 静宁县| 恩平市| 平原县| 大宁县| 昭通市| 平阴县| 太原市| 揭西县| 清水河县| 屏东县| 滕州市| 华亭县| 五常市| 湛江市| 南华县| 丰镇市| 肥城市| 古丈县| 宜君县| 昂仁县| 嘉黎县| 类乌齐县| 贡山|