uCOS II訊號量學習

2021-05-04 07:09:56 字數 3368 閱讀 1270

ucos-ii學習環境的建立可以參考這個帖子:

1、 相關背景知識

訊號量為作業系統處理臨界區問題和程序間同步提供了一種有效的機制。訊號量本身不具備資料傳輸的功能,它只是資源的外部標識,通過該標識可以判斷該資源是否可用。訊號量在此過程中負責資料操作的互斥、同步等功能。訊號量的行為常用p操作和v操作來表示,簡稱pv操作。任務對資源進行p操作,即意味著申請占有乙個資源;任務對資源進行v操作,即意味著釋放占有的資源。如果初始資源數為1,那麼該資源就是互斥資源,即一次只允許乙個任務使用。

2、 ucos-ii中任務之間的通訊和同步

在ucos-ii中學習訊號量就不得不提ucos-ii中任務之間的通訊與同步機制。在ucos-ii中乙個任務可以通過事件控制塊(ecb)來向另外的任務發訊號,所有的訊號都被看做為事件。這裡,事件可以是訊號量、郵箱或者訊息佇列等。也就是說ucos-ii對訊號量、郵箱或者訊息佇列等事件定義了乙個相同的資料結構——ecb。ucos-ii 通過ucos-ii_ii.h 中定義的os_event 資料結構來維護乙個事件控制塊的所有資訊,下面是其詳細**描述:

其中oseventtype設定具體事件型別,在ucos-ii中可以設定為訊號量(os_event_sem)、郵箱(os_event_type_mbox)或訊息佇列(os_event_type_q)。訊號量主要涉及的域為oseventcnt(訊號量值),oseventgrp,oseventtbl。

3、ucos-ii中的訊號量

ucos-ii 中的訊號量由兩部分組成:乙個是訊號量的計數值,它是乙個16 位的無符號整數(0 到65,535 之間);另乙個是由等待該訊號量的任務組成的等待任務表。

在使用乙個訊號量之前,首先要建立該訊號量,對訊號量的初始計數值賦值。該初始值為0 到65,535 之間的乙個數。如果訊號量是用來表示乙個或者多個事件的發生,那麼該訊號量的初始值應設為0。如果訊號量是用於對共享資源的訪問,那麼該訊號量的初始值應設為1。最後,如果該訊號量是用來表示允許任務訪問n 個相同的資源,那麼該初始值顯然應該是n,並把該訊號量作為乙個可計數的訊號量使用。

ucos-ii 提供了5 個對訊號量進行操作的函式。它們是:ossemcreate(),ossempend(),ossempost(),ossemaccept()和ossemquery()函式。

os_event *ossemcreate (int16u cnt)

建立乙個訊號量,建立工作必須在任務啟動之前完成。該函式的功能主要是獲取乙個事件控制塊ecb,然後初始化,引數為訊號量值。如果建立成功函式則返回乙個指向該事件控制塊的指標。這裡需要注意的是,在ucos-ii中,訊號量一旦建立就不能刪除了。

void ossempend (os_event *pevent, int16u timeout, int8u *err)

等待乙個訊號量,本函式主要應用於下面三種場合:

1、任務試圖獲得共享資源的使用權;

2、任務需要與其他任務或中斷同步;

3、任務需要等待特定事件發生

該函式的第乙個引數是指向等待訊號量對應事件控制塊的指標;第二個引數是等待的時間,如果為0則表示一直等待;第三個引數用來儲存出錯資訊。在呼叫ossempend()時一定要檢查err的值,然後再進行後面的操作。err的值一共有os_err_pend_isr、os_err_pevent_null(沒有建立該訊號量)、os_err_event_type(型別不匹配)、os_no_err(成功)和os_timeout(超時)5個值。

int8u ossempost (os_event *pevent)

傳送乙個訊號量,該函式的第乙個引數是指向需要傳送訊號量對應事件控制塊的指標。

int16u ossemaccept (os_event *pevent)

無等待的請求乙個訊號量,如果任務請求的訊號量暫時無效,則該任務簡單返回。中斷服務子程式要請求訊號量時必須使用該函式。

int8u ossemquery (os_event *pevent, os_sem_data *pdata)

查詢乙個訊號量的當前狀態,函式的第乙個引數為指向需要查詢訊號量對應事件控制塊的指標;第二個引數為指向用於記錄訊號量資訊的資料結構os_sem_data的指標。該資料結構是事件控制塊的簡化版,裡面只包含事件控制塊中跟訊號量相關的域,即只包含oseventcnt、oseventgrp和oseventtbl三項。

3、 ucos-ii訊號量例項

該例項主要模擬串列埠驅動的緩衝區實現,由於序列裝置存在外設處理速度和cpu速度不匹配的問題,所以需要緩衝區。在例項中每個串列埠有兩個環狀佇列緩衝區,同時有兩個訊號量。乙個用來指示接收位元組(rxsem),另乙個用來指示傳送位元組(txsem)。每個環狀佇列包括下面四個要素:

儲存資料(int8u陣列);

1)、包含環狀緩衝區位元組數的計數器;

2)、環狀緩衝區中指向將被放置的下一位元組的指標;

3)、環狀緩衝區中指向被取出的下一位元組的指標

兩個環形佇列緩衝區乙個為資料接收緩衝區rxbuf,另乙個為資料傳送緩衝區txbuf。

對兩個緩衝區進行操作的函式主要有四個:serialgettxchar()、serialputrxchar()、serialputchar(int8u c)和serialgetchar()。其中函式serialputchar(int8u c)和serialgetchar()是應用程式介面,serialputchar()把資料放到txbuf中,serialgetchar()從rxbuf中獲取資料。函式serialputrxchar()用來將接收的位元組放到rxbuf中,如果接收緩衝區已滿,則該位元組被丟棄。當位元組插入到緩衝區後,serialputrxchar()傳送資料接收訊號量,將資料己到的訊息傳達給所有等待的任務。函式serialgettxchar()從txbuf中接收資料然後傳送出去。

4、 測試例項

測試程式建立了四個任務,taskstart、taskcom、taskget和taskput。任務tasksatart設定中斷向量、開啟時鐘節拍、設定顯示介面和建立taskcom、taskget和taskput三個任務。這裡需要注意的是使用者必須在多工系統啟動以後再開啟時鐘節拍器,也就是在呼叫osstart()之後。換句話說,在呼叫osstart()後做的第一件事就是初始化定時器中斷。任務taskcom模擬資料的傳輸,就是把資料從txbuf中取出然後放入rxbuf中。任務taskget從rxbuf中讀取資料然後顯示到螢幕上。任務taskput響應鍵盤中斷,從鍵盤接收資料然後放到txbuf中。為了對比,任務taskput除了把資料放到txbuf中同時還將其顯示到螢幕上。

下面是測試結果:

ucos ii 訊號量的使用

訊號量使用主要涉及三個函式 ossemcreat ossempend ossempost 第乙個負責建立乙個訊號量,同時需要的引數是設定訊號量的值 第二個是等待該訊號量,當訊號量值為0時,將呼叫改函式的任務加入該訊號量的等待任務列表 中,當訊號量值大於0時,該函式緊緊將訊號量值減1 第三個函式負責置...

UCOSII 訊號量的使用

訊號量的使用 使用訊號量之前首先要對訊號量有乙個本質的認識 1 訊號量的含義 訊號量是一類事件,使用訊號量的最初目的是為了給共享資源 設 立乙個標誌,該標誌表示共享資源的占用情況,這樣,當乙個任務在訪問共 享資源之前,就可以對這個標誌進行查詢,從而在了解資源被占用的情況之後 再來決定自己的行為。2 ...

訊號量學習

一 概念 訊號量是乙個整數,這個整數允許多程序或多執行緒同步他們的操作。這個整數必須大於等於0.linux庫函式中,類似有名對映 匿名對映,有名管道 無名管道,訊號量也有有名訊號量和匿名信號量。匿名信號量在記憶體中,不在檔案系統中,一般用於執行緒之間的同步 有名訊號量需要建立檔案,一般用於程序之間的...