新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > ucos-ii學習筆記——信號量的原理及使用

        ucos-ii學習筆記——信號量的原理及使用

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

        Author:zhangbin

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

        學習筆記

        forucos-iiPC

        redesignedbyzhangbin

        2012-10-7

        versions:V-0.1

        AllRightsReserved

        #include"INCLUDES.h"

        #defineTASK_STK_SIZE512

        char*s1="MyTask";

        char*s2="YouTask";

        INT8Uerr;//定義一個錯誤信息

        INT8Uy=0;

        OS_EVENT*Fun_Semp;//聲明信號量是事件控制塊ECB類型的

        //注意,前面有一個例子2定義了互斥信號量,定義如下

        //BOOLEANac_key;//信號量,互斥信號量實質上就是一個標志位,是一個全局變量,來標志共享資源的訪問情況

        //這樣,當已經有任務訪問共享資源時,其他的任務就不能訪問,知道該資源未被訪問,其他的任務才可以進行訪問

        //注意這兩個信號量的區別和使用情況

        OS_STKStartTaskStk[TASK_STK_SIZE];//定義任務堆棧區

        OS_STKMyTaskStk[TASK_STK_SIZE];

        OS_STKYouTaskStk[TASK_STK_SIZE];

        voidFun(INT8Ux,INT8Uy);

        voidStartTask(void*data);

        voidMyTask(void*data);

        voidYouTask(void*data);

        voidmain(void)

        {

        Fun_Semp=OSSemCreate(1);//在主函數中創建信號量返回值為創建的信號量指針,參數是信號量的計數器的值

        //用該參數對信號量計數器OSEventCnt進行初始化

        //1即代表只創建一個信號量,代表信號量用于對共享資源的訪問(例如,把它當做二值信號量使用),詳見P166

        OSInit();

        PC_DOSSaveReturn();

        PC_VectSet(uCOS,OSCtxSw);

        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],1);//創建任務函數

        OSTaskCreate(YouTask,(void*)0,&YouTaskStk[TASK_STK_SIZE-1],2);//創建任務函數

        for(;;)

        {

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

        if(PC_GetKey(&key)==TRUE)

        {

        if(key==0x1B)

        {

        PC_DOSReturn();

        }

        }

        OSTimeDlyHMSM(0,0,3,0);

        }

        }

        //MyTask的函數代碼

        voidMyTask(void*pdata)

        {

        #ifOS_CRITICAL_METHOD==3

        OS_CPU_SRcpu_sr;

        #endif

        pdata=pdata;

        for(;;)

        {

        OSSemPend(Fun_Semp,0,&err);//請求信號量參數Fun_Semp是信號量指針0那一項是等待時限timeout,0表示無限等待

        //err表示錯誤信息

        PC_DispStr(0,++y,s1,DISP_BGND_BLACK+DISP_FGND_WHITE);//顯示MyTask字符串

        Fun(7,y);//調用Fun函數

        OSSemPost(Fun_Semp);//發送信號量釋放信號量,函數的參數Fun_Semp代表信號量的指針

        OSTimeDlyHMSM(0,0,1,0);

        }

        }

        voidYouTask(void*pdata)

        {

        #ifOS_CRITICAL_METHOD==3//AllocatestorageforCPUstatusregister

        OS_CPU_SRcpu_sr;

        #endif

        pdata=pdata;

        for(;;)

        {

        OSSemPend(Fun_Semp,0,&err);//請求信號量

        PC_DispStr(0,++y,s2,DISP_BGND_BLACK+DISP_FGND_WHITE);

        Fun(7,y);//調用FUN函數

        OSSemPost(Fun_Semp);//釋放信號量

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

        }

        }

        //公共的函數Fun的代碼

        voidFun(INT8Ux,INT8Uy)

        {

        PC_DispStr(x,y,"CallingFUN()",DISP_BGND_BLACK+DISP_FGND_WHITE);//顯示字符串,表示調用了Fun函數

        }

        //創建信號量時,用的參數為1,即Fun_Semp=OSSemCreate(1);,只創建了一個信號量,這種情況一般是信號量用于對

        //共享資源的訪問(例如,可以把它當做二值信號量使用)

        //在上面的程序中,當MyTask運行時,先請求獲得了信號量,對共享資源Fun函數進行訪問,由于只創建了一個信號量,

        //所以在MyTask的訪問期間,即使任務YouTask也進行申請信號量,此時OSEventCnt是值已經為0了,所以會把任務

        //YouTask列入任務等代表OSEventTbl[]中,使任務處于等待狀態。

        //只有等MyTask對Fun函數訪問完成了,調用OSSemPost(Fun_Semp);釋放了信號量,該釋放信號量的函數會先檢查任務等待

        //表中是否還有等待信號量的任務,如果有,則使任務進入就緒態后,調用調度器OS_Sched()引發一次任務調度,去運行等待

        //任務列表中優先級最高的任務。如果沒有,則就把信號量計數器OSSemCnt加1.

        //所以任務YouTask要想訪問Fun()函數,必須等到任務MyTask對Fun訪問完畢,釋放了信號量之后,才能訪問,反之亦然

        //所以由上面可以看出,只創建一個信號量,即OSSemCreate(1);,作用就相當于使用一個二值信號量,標志共享資源是否正在

        //被訪問

        //看懂了上面的分析,也就可以解釋實驗現象了,由于YouTask等待2s,MyTask等待1s,所以有可能在MyTask訪問Fan函數期間,YouTask

        //也來訪問(也有可能是反過來),但是由于信號量已經被MyTask占用了,所YouTask只好等待,MyTask使用完了,釋放了信號量,YouTask才能正常使用Fun函數

        //這樣也就解決了多任務對共享資源的使用的問題,使任務之間得到了同步

        //要仔細分析信號量工作的原理,把上面的內容看懂了,基本上也就可以使用信號量了



        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 玛曲县| 阿城市| 深水埗区| 铜陵市| 北安市| 贵港市| 上虞市| 监利县| 乳源| 宝山区| 星子县| 昌宁县| 佛学| 南皮县| 辽阳县| 泽州县| 北川| 正安县| 青川县| 烟台市| 上饶市| 巨野县| 额尔古纳市| 伊宁县| 富源县| 镇平县| 太谷县| 梁平县| 海门市| 图木舒克市| 中宁县| 株洲县| 延边| 兴山县| 疏勒县| 门头沟区| 无为县| 肇庆市| 合川市| 饶平县| 佛山市|