1:計數訊號量
1.1 建立訊號量
當事件控制塊os_event中的oseventtype=os_event_type_sem時,則表示此處建立的事件為訊號量。
上面為計數訊號量的建立函式,建立函式不能在中斷中呼叫,在全域性的事件控制塊列表中取出乙個事件控制塊pevent,對pevent進行初始化操作。設定此事件的型別為;oseventtype為os_event_type_sem。同時呼叫函式來初始化os_eventwaitlistinit()事件控制塊使事件等待列表中沒有等待的任務。
1.2 獲取訊號量
當某個任務獲取計數訊號量時,根據當前訊號量的值判斷此任務是繼續執行還是掛起。函式
void ossempend (os_event *pevent, int16u timeout, int8u *perr)來實現對訊號量的獲取。當前執行的任務不一定是系統中優先順序最高的任務,只能說是在任務排程之前,就緒佇列中優先順序最高的任務。
上面的**設定tcb的當前狀態為:os_stat_sem,定義如下:表示當前的任務正在等待訊號量
#define os_stat_sem 0x01u /* pending on semaphore
之後呼叫函式os_eventtaskwait()使當前的任務新增到等待事件表中並使任務從任務就緒表中刪除。
之後進行任務的排程 os_sched(); 任務排程之後,系統將cpu的使用許可權人給就緒表中最高優先順序的任務。之前看到在系統tick處理函式中進行中斷級任務的排程。其有如下**:
上面的**是在函式ostimetick()中,在任務的等待時間不為0時if (ptcb->ostcbdly != 0),更新任務的扥帶時間及任務的就緒狀態。
同時在tcb資料結構的第一次欄位是:
os_stk *ostcbstkptr; /* pointer to current top of stack */
在無論是任務級還是中斷及的任務切換,在切換的時候都會當前函式的指標儲存在任務的堆疊中。當等待事件的任務滿足等待條件或者等待超時的時候,就緒表中最高優先順序的任務從自己的堆疊pc指標處繼續執行。
1.3 訊號量的釋放
當對共享資源訪問結束指數之後,需要對訊號量進行釋放操作。在對訊號量計數值進行+1操作之前必須對是否還要任務等待此訊號量事件進行判斷。當有任務等在此訊號量事件時,呼叫函式os_eventtaskrdy()是任務從等待事件表中移除並使此任務進入就緒狀態。
1.4 訊號量的刪除
os_event *ossemdel (os_event *pevent, int8u opt, int8u *perr)
上面的函式為計數訊號量的刪除函式,其中opt的取值如下:
opt == os_del_no_pend delete semaphore only if no task pending
opt == os_del_always deletes the semaphore even if tasks are waiting.in this case, all the tasks pending will be readied.
函式中首先判斷任務等待組是否為0即可以確定是否有等待此事件的任務存在。
if (pevent->oseventgrp != 0) else
之後根據opt的取值分別進行處理
當opt=os_del_no_pend 時
case os_del_no_pend: /* delete semaphore only if no task waiting */
if (tasks_waiting == os_false) else
break;
在此opt之下,之後當沒有等待任務的時候才能進行此操作,將事件型別改為:
oseventtype = os_event_type_unused;即此事件還沒有進行賦值操作。同時將此事件控制塊新增到全域性的空閒控制塊oseventfreelist 鍊錶中。
當opt=os_del_always
時,無論是否有任務等待此事件,將等待此事件的任務從等待表中刪除。
case os_del_always: /* always delete the semaphore */
while (pevent->oseventgrp != 0)
#if os_event_name_size > 1
pevent->oseventname[0] = '?'; /* unknown name */
pevent->oseventname[1] = os_ascii_nul;
#endif
pevent->oseventtype = os_event_type_unused;
pevent->oseventptr = oseventfreelist; /* return event control block to free list */
pevent->oseventcnt = 0;
oseventfreelist = pevent; /* get next free event control block */
os_exit_critical();
if (tasks_waiting == os_true)
*perr = os_err_none;
pevent_return = (os_event *)0; /* semaphore has been deleted */
break;
同時當刪除的事件有任務等待時,在進行乙個任務排程。
UCOS之訊號量
c os ii 中的訊號量由兩部分組成 乙個是訊號量的計數值,它是乙個 16 位的無符號整數 0 到65,535之間 另乙個是由等待該訊號量的任務組成的等待任務表。使用者要在 os cfg.h中將os sem en開關量常數置成1,這樣 c os ii 才能支援訊號量。當訊號量不為0時,任務即可獲得...
ucos訊號量理解1
本文主要來自 ucos中提供了好幾個用於同步事件以及共享資源訪問的機制,目前我看明白的有訊號量,互斥訊號量,事件標誌組。下面談談自己對他們的理解 互斥互斥,意思就是我用了你就不能用,你用了我就不能用。永遠都只有乙個人獨佔這個東西 舉個例子 比如說印表機。我任務1現在讓他列印 靜夜思 那麼在我還沒列印...
ucos訊號量訊息佇列
全域性變數 static int msg int os q data msg 訊息佇列主任務 void start task void p arg led任務0 void led0 task void p arg if err os err none ostimedlyhmsm 0,0,3,0,os...