<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > ucos-ii學(xué)習(xí)筆記——信號(hào)量的原理及使用

          ucos-ii學(xué)習(xí)筆記——信號(hào)量的原理及使用

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

          Author:zhangbin

          本文引用地址:http://www.ex-cimer.com/article/201611/322849.htm

          學(xué)習(xí)筆記

          forucos-iiPC

          redesignedbyzhangbin

          2012-10-7

          versions:V-0.1

          AllRightsReserved

          #include"INCLUDES.h"

          #defineTASK_STK_SIZE512

          char*s1="MyTask";

          char*s2="YouTask";

          INT8Uerr;//定義一個(gè)錯(cuò)誤信息

          INT8Uy=0;

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

          //注意,前面有一個(gè)例子2定義了互斥信號(hào)量,定義如下

          //BOOLEANac_key;//信號(hào)量,互斥信號(hào)量實(shí)質(zhì)上就是一個(gè)標(biāo)志位,是一個(gè)全局變量,來標(biāo)志共享資源的訪問情況

          //這樣,當(dāng)已經(jīng)有任務(wù)訪問共享資源時(shí),其他的任務(wù)就不能訪問,知道該資源未被訪問,其他的任務(wù)才可以進(jìn)行訪問

          //注意這兩個(gè)信號(hào)量的區(qū)別和使用情況

          OS_STKStartTaskStk[TASK_STK_SIZE];//定義任務(wù)堆棧區(qū)

          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);//在主函數(shù)中創(chuàng)建信號(hào)量返回值為創(chuàng)建的信號(hào)量指針,參數(shù)是信號(hào)量的計(jì)數(shù)器的值

          //用該參數(shù)對(duì)信號(hào)量計(jì)數(shù)器OSEventCnt進(jìn)行初始化

          //1即代表只創(chuàng)建一個(gè)信號(hào)量,代表信號(hào)量用于對(duì)共享資源的訪問(例如,把它當(dāng)做二值信號(hào)量使用),詳見P166

          OSInit();

          PC_DOSSaveReturn();

          PC_VectSet(uCOS,OSCtxSw);

          OSTaskCreate(StartTask,(void*)0,&StartTaskStk[TASK_STK_SIZE-1],0);//創(chuàng)建起始函數(shù)

          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);//創(chuàng)建任務(wù)函數(shù)

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

          for(;;)

          {

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

          if(PC_GetKey(&key)==TRUE)

          {

          if(key==0x1B)

          {

          PC_DOSReturn();

          }

          }

          OSTimeDlyHMSM(0,0,3,0);

          }

          }

          //MyTask的函數(shù)代碼

          voidMyTask(void*pdata)

          {

          #ifOS_CRITICAL_METHOD==3

          OS_CPU_SRcpu_sr;

          #endif

          pdata=pdata;

          for(;;)

          {

          OSSemPend(Fun_Semp,0,&err);//請(qǐng)求信號(hào)量參數(shù)Fun_Semp是信號(hào)量指針0那一項(xiàng)是等待時(shí)限timeout,0表示無限等待

          //err表示錯(cuò)誤信息

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

          Fun(7,y);//調(diào)用Fun函數(shù)

          OSSemPost(Fun_Semp);//發(fā)送信號(hào)量釋放信號(hào)量,函數(shù)的參數(shù)Fun_Semp代表信號(hào)量的指針

          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);//請(qǐng)求信號(hào)量

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

          Fun(7,y);//調(diào)用FUN函數(shù)

          OSSemPost(Fun_Semp);//釋放信號(hào)量

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

          }

          }

          //公共的函數(shù)Fun的代碼

          voidFun(INT8Ux,INT8Uy)

          {

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

          }

          //創(chuàng)建信號(hào)量時(shí),用的參數(shù)為1,即Fun_Semp=OSSemCreate(1);,只創(chuàng)建了一個(gè)信號(hào)量,這種情況一般是信號(hào)量用于對(duì)

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

          //在上面的程序中,當(dāng)MyTask運(yùn)行時(shí),先請(qǐng)求獲得了信號(hào)量,對(duì)共享資源Fun函數(shù)進(jìn)行訪問,由于只創(chuàng)建了一個(gè)信號(hào)量,

          //所以在MyTask的訪問期間,即使任務(wù)YouTask也進(jìn)行申請(qǐng)信號(hào)量,此時(shí)OSEventCnt是值已經(jīng)為0了,所以會(huì)把任務(wù)

          //YouTask列入任務(wù)等代表OSEventTbl[]中,使任務(wù)處于等待狀態(tài)。

          //只有等MyTask對(duì)Fun函數(shù)訪問完成了,調(diào)用OSSemPost(Fun_Semp);釋放了信號(hào)量,該釋放信號(hào)量的函數(shù)會(huì)先檢查任務(wù)等待

          //表中是否還有等待信號(hào)量的任務(wù),如果有,則使任務(wù)進(jìn)入就緒態(tài)后,調(diào)用調(diào)度器OS_Sched()引發(fā)一次任務(wù)調(diào)度,去運(yùn)行等待

          //任務(wù)列表中優(yōu)先級(jí)最高的任務(wù)。如果沒有,則就把信號(hào)量計(jì)數(shù)器OSSemCnt加1.

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

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

          //被訪問

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

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

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

          //要仔細(xì)分析信號(hào)量工作的原理,把上面的內(nèi)容看懂了,基本上也就可以使用信號(hào)量了



          評(píng)論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();