ucos訊號量理解1

2021-07-25 16:58:48 字數 3157 閱讀 4532

本文主要來自:

ucos中提供了好幾個用於同步事件以及共享資源訪問的機制,目前我看明白的有訊號量,互斥訊號量,事件標誌組。下面談談自己對他們的理解:

互斥互斥,意思就是我用了你就不能用,你用了我就不能用。永遠都只有乙個人獨佔這個東西~!舉個例子:比如說印表機。

我任務1現在讓他列印《靜夜思》,那麼在我還沒列印完之前,別的任務就不能命令印表機去列印別的東西。否則如果任務2讓他列印《春曉》,那最後列印出來的會是什麼~????反正肯定不是任務1想要的,肯定也不是任務2想要的。

上面講的比較通俗。印表機就是共享資源,誰都可以訪問他~!但是同一時間,肯定要保證只有1個任務再操作印表機。那樣才能得到大家想要的結果。也就是要獨佔共享資源的訪問權~!

ucos2中通過互斥訊號量來解決這個問題。簡單說就是任務1開始訪問印表機的時候,先去查詢這個互斥訊號量是否有效,有效,說明沒人在訪問印表機,這時任務1就把這個互斥訊號量置無效,然後開始操作印表機。這樣,每個任務再操作印表機前都要去查詢這個互斥訊號量時候有效。無效就等,等到有效才可以訪問,或者等到不耐煩了(術語叫等待超時)就不等了~!任務一直到用完了印表機後才把訊號量置有效,這時其他任務才有可能去訪問,操作印表機。

這裡又有乙個問題:再任務1操作印表機器件,可能有多個任務申請印表機的所有權。那麼再任務1結束後,我應該給誰用呢~~??也許我們馬上就反應過來了~廢話~!!當然是排隊了~~誰先到的誰用啊~~~。沒錯,這是一種機制,誰最先等待共享資源,就給誰用。但是~!再ucos裡面2.52版本還不支援這種方式。他用的另外一種方法!如果你和你boss都再等著用印表機,你先到的,這個時候任務1結束了對印表機的操作。你說你敢先用麼~???(除非你第二天不想幹了~~)你肯定先讓老闆先用,這就是ucos的實現方式,基於優先順序,任務1結束對印表機的操作後,ucos再等待佇列中看那個等待任務優先順序最高,就先給他用~!即使他是最晚才等待的~!!(這就是boss的威力~!)

關於事件等待列表,有興趣的可以去看看事件控制塊ecb的內容,不在本文討論。當然,ucos中的互斥訊號量還有許多要素,比如說他的繼承優先順序之類的。本文旨在說明它是幹嘛用的,至於其他請參考相關書籍。

下面的**釋了互斥訊號量的基本用法:(簡單的兩個任務,沒有包含多工等待的情況)

至於訊號量,和互斥訊號量是用區別的,簡單來說(個人理解,歡迎糾正)就是互斥訊號量再同一時刻,任務得到互斥訊號量量後是獨佔共享資源的,在他沒有釋放訊號量之前,任何其他任務都是不能訪問共享資源的。而訊號量的不同在於。訊號量可以設定乙個值,允許最多又幾個任務同時去訪問共享資源。比如我給他設定乙個5,那麼對多就有5個任務能同時訪問共享資源。每個任務獲得訊號量的時候就把訊號量計數器減去1,這樣,再第五個任務獲取後,計數器是0.當第六個任務要去訪問的時候申請訊號量就只能等待了,等到之前的任務發乙個訊號出來,這樣第六個任務才能去訪問共享資源。

互斥訊號量可以看成特殊情況下的訊號量,他的計數器就是0或者1,只在這兩個之間徘徊。

舉個例子(不一定恰當,歡迎糾正):

現在有很多串列埠擴充套件卡,一張卡能擴充套件出好幾個串列埠,比如說4個,這個擴充套件卡就是乙個共享資源。現在定義乙個訊號量semcom,初始給他4,那麼可以有4個任務去訪問這個資源,他每次就給這4個任務分配不同的串列埠。每個任務要訪問這個擴充套件卡就要去測試semcom看看他時候有訊號。這樣,前4個任務申請訊號後,訊號量計數器就等於0了,這樣,在第五個任務要去訪問擴充套件卡的時候,他也去測試這個semcom,發現訊號量無效,他只能等了~!等到之前的任務釋放乙個串列埠為止,如果不用訊號量,那麼任務五可能就會去訪問擴充套件卡上的串列埠1,而串列埠1之前已經分配給了任務1了,~造成什麼後果就自己想想吧~~~~如果用互斥訊號量,那麼無疑浪費了資源,~~~那你就買個擴充套件1個串列埠的卡就行了~~你買個擴充套件4個的然後你用互斥訊號量~~~不是擺明再說你是富二代麼~~~

等待訊號的任務在有訊號以後也是按照等待列表中優先順序最高的任務先得到訊號處理。有關訊號量的具體資料結構參考事件控制塊ecb的內容,具體操作參考訊號量函式等。在此不做介紹

下面這個圖說明了以上的例子:(

在理解訊號量和互斥訊號量的時候都可以模擬,因為他們在ucos2裡面都通過相同的時間控制塊即ecb這個資料結構來實現,理解了乙個就很好能看懂另外乙個,設定更後面的郵箱和訊息佇列,也能和訊號量之類的模擬來學習,他們都有通過ecb來維護。但是事件標誌組比較特別,他是ucos2所有這些核心事件裡面沒有用到ecb的。他有自己的做法。不太合群。什麼是事件標誌組?

上面說的訊號量,互斥訊號量。都是用來同步任務對共享資源的訪問,防止衝突而設立的。事件標誌組----他是用來同步幾個任務,協調幾個任務工作而設立的。打個比方你現在要打個**,打**這個任務要執行,你必須有手機吧!那你要先執行買手機這個任務,你手機有了,沒話費~你也大不了吧~,也就是說打**這個任務要等買手機這個任務和充話費這個任務都完成了以後你才能去開始打**這個任務。事件標誌組就是用來標誌買手機或者充話費這兩個任務完成了沒有。完成了的話他們會相應的置位事件標誌組裡面的某些標誌位。那麼打**這個任務。發現事件標誌組裡面買手機對應的位和充話費對應的位都置位了以後就明白,現在可以開始打**了~!實際中比如你想要讀資料,那你肯定要等資料採集更新好了以後你去讀才有意義吧~所以資料採集和讀取資料這兩個任務也可以用事件標誌組來實現。當然,事件標誌組不一定只用於兩個任務之間,通過對頭檔案的修改,可以讓事件標誌組達到32位,你可以用事件標誌組來協調多個任務的合理執行。達到你預期想達到的目的!事件標誌組就是專門幹這個活的。

事件標誌組的結構比其他的會複雜一點。沒乙個事件標誌組都維護這自己的乙個等待佇列的雙向鍊錶。每個事件標誌組的節點裡面都有乙個指標和相應的任務控制塊tcb一一對應。至於事件標誌組的具體實現方法,可以自己去看看源**。只要

懂得一些淺顯的雙向鍊錶的知識,大概理解他的運作機制不會很難。

下面這幅圖大概反應出了事件標誌組是如何協調任務工作的:

終於要完了~~總的來說,到目前為止,都還能大概理解ucos的每個模組的實現機理。但是是不是真的懂了自己不敢說。畢竟要等能真的自己動手一直,再ucos2系統上開發出應用那樣才能真的算懂了。也知道到那個時候,才有可能能對其有更深的理解。個人認為初看ucos2的時候只要能有一些基本的資料結構基礎如線性表,堆疊,佇列,單鏈表,雙鏈表之類的就差不多。在看的過程中慢慢體會作者的思想和學習別人的程式設計思路才是最重要的。

UCOS之訊號量

c os ii 中的訊號量由兩部分組成 乙個是訊號量的計數值,它是乙個 16 位的無符號整數 0 到65,535之間 另乙個是由等待該訊號量的任務組成的等待任務表。使用者要在 os cfg.h中將os sem en開關量常數置成1,這樣 c os ii 才能支援訊號量。當訊號量不為0時,任務即可獲得...

ucos 計數訊號量

1 計數訊號量 1.1 建立訊號量 當事件控制塊os event中的oseventtype os event type sem時,則表示此處建立的事件為訊號量。上面為計數訊號量的建立函式,建立函式不能在中斷中呼叫,在全域性的事件控制塊列表中取出乙個事件控制塊pevent,對pevent進行初始化操作...

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