UCOS系統學習記錄1 OSSemCreate(INT16U cnt)函式使用方法
在ucos-II中,為了實現任務之間的同步,用到的同步機制有:訊號量,郵箱和訊息佇列。其中這裡我主要說下對訊號量的使用經驗。
訊號量在建立時,呼叫OSSemCreate(INT16U cnt)函式。
cnt為訊號量的初始值。對cnt賦予不同的值,所起到的作用不同。如果Semp = OSSemCreate(0), 該訊號量表示等待一個事件或者多個事件的發生。
如果我們想對一個公共資源進行互斥訪問,例如:
如果我們想讓兩個任務Task1和Task2都可以呼叫Fun()函式,但不能同時呼叫,最好定義Semp = OSSemCreate(1),同理在各自的任務中都需要呼叫OSSemPend(Semp,0,&err)請求此訊號量
同理,如果一個任務要等待n個事件發生後才能執行,則應定義為Semp = OSSemCreate(n)。然後在這n個任務分別執行時呼叫OSSemPost(Semp),直到這n個事件均發生後,這個任務才能執行。
OSSemCreate(cnt)賦初始值cnt,OSSemPend一次,cnt-- 一次,OSSemPost一次,cnt++一次。
1、OSSemCreate (0);
......
OS_EVENT *Fun_Semp;
......
Fun_Semp = OSSemCreate (0);
......
void MyTask (void *pdata)
{
.....
for (;;)
{
OSSemPend(Fun_Semp,0,&err); //請求訊號量
PC_DispStr(0,++y, s1, DISP_BGND_BLACK+DISP_FGND_WHITE );
OSTimeDlyHMSM(0, 0, 1, 0); //等待1秒
}
}
......
void YouTask (void *pdata)
{
......
for (;;)
{
PC_DispStr(0,++y, s2, DISP_BGND_BLACK+DISP_FGND_WHITE );
if(YouTaskRun==5)
OSSemPost(Fun_Semp); //傳送訊號量
YouTaskRun++;
OSTimeDlyHMSM(0, 0, 2, 0); //等待2秒
}
}
在上例中,MyTask 一直在等待訊號量,在訊號量沒有到來之前無法執行。只有在YouTask 運行了5次,YouTaskRun==5之後,OSSemPost(Fun_Semp); //傳送訊號量,MyTask 才得以執行。
2、OSSemCreate (1);
.....
OS_EVENT *Fun_Semp;
.....
Fun_Semp = OSSemCreate (1);
.....
void MyTask (void *pdata)
{
.....
for (;;)
{
OSSemPend(Fun_Semp,0,&err); //請求訊號量
PC_DispStr(0,++y, s1, DISP_BGND_BLACK+DISP_FGND_WHITE );
OSSemPost(Fun_Semp); //傳送訊號量
OSTimeDlyHMSM(0, 0, 1, 0); //等待1秒
}
}
void YouTask (void *pdata)
{
for (;;)
{
OSSemPend(Fun_Semp,0,&err); //請求訊號量
PC_DispStr(0,++y, s2, DISP_BGND_BLACK+DISP_FGND_WHITE );
OSSemPost(Fun_Semp); //傳送訊號量
OSTimeDlyHMSM(0, 0, 2, 0); //等待2秒
}
}
在上例中,MyTask、YouTask 都在 等待訊號量,由於MyTask優先順序高,首先得到訊號量開始執行。此時YouTask 還在等待訊號量。MyTask 執行完畢,OSSemPost(Fun_Semp); //傳送訊號量。YouTask 得到訊號量執行後傳送訊號量,如此反覆。