ucos 計數訊號量

2021-06-19 05:47:41 字數 3335 閱讀 7547

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...