溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

FreeRTOS實時操作系統(tǒng)信號量基礎(chǔ)知識點有哪些

發(fā)布時間:2022-04-08 13:52:21 來源:億速云 閱讀:210 作者:iii 欄目:開發(fā)技術(shù)

今天小編給大家分享一下FreeRTOS實時操作系統(tǒng)信號量基礎(chǔ)知識點有哪些的相關(guān)知識點,內(nèi)容詳細(xì),邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。

1.信號量簡介

FreeRTOS的信號量包括二進(jìn)制信號量、計數(shù)信號量、互斥信號量(以后簡稱互斥量)和遞歸互斥信號量(以后簡稱遞歸互斥量)。

我們可以把互斥量和遞歸互斥量看成特殊的信號量?;コ饬亢托盘柫吭谟梅ㄉ喜煌?/p>

信號量用于同步,任務(wù)間或者任務(wù)和中斷間同步;互斥量用于互鎖,用于保護(hù)同時只能有一個任務(wù)訪問的資源,為資源上一把鎖。

信號量用于同步時,一般是一個任務(wù)(或中斷)給出信號,另一個任務(wù)獲取信號;互斥量必須在同一個任務(wù)中獲取信號、同一個任務(wù)給出信號。

互斥量具有優(yōu)先級繼承,信號量沒有。

互斥量不能用在中斷服務(wù)程序中,信號量可以。

創(chuàng)建互斥量和創(chuàng)建信號量的API函數(shù)不同,但是共用獲取和給出信號API函數(shù);

2.二進(jìn)制信號量

二進(jìn)制信號量既可以用于互斥功能也可以用于同步功能。

二進(jìn)制信號量和互斥量非常相似,但是有一些細(xì)微差別:互斥量包含一個優(yōu)先級繼承機(jī)制,二進(jìn)制信號量則沒有這個機(jī)制。這使得二進(jìn)制信號量更好的用于實現(xiàn)同步(任務(wù)間或任務(wù)和中斷間),互斥量更好的用于實現(xiàn)簡單互斥。本節(jié)僅描述用于同步的二進(jìn)制信號量。

信號量API函數(shù)允許指定一個阻塞時間。當(dāng)任務(wù)企圖獲取一個無效信號量時,任務(wù)進(jìn)入阻塞狀態(tài),阻塞時間用來確定任務(wù)進(jìn)入阻塞的最大時間,阻塞時間單位為系統(tǒng)節(jié)拍周期時間。如果有多個任務(wù)阻塞在同一個信號量上,那么當(dāng)信號量有效時,具有最高優(yōu)先級別的任務(wù)最先解除阻塞。

可以將二進(jìn)制信號量看作只有一個項目(item)的隊列,因此這個隊列只能為空或滿(因此稱為二進(jìn)制)。任務(wù)和中斷使用隊列無需關(guān)注誰控制隊列---只需要知道隊列是空還是滿。利用這個機(jī)制可以在任務(wù)和中斷之間同步。

考慮這樣一種情況,一個任務(wù)用來維護(hù)外設(shè)。使用輪詢的方法會浪費CPU資源并且妨礙其它任務(wù)執(zhí)行。更好的做法是任務(wù)的大部分時間處于阻塞狀態(tài)(允許其它任務(wù)執(zhí)行),直到某些事件發(fā)生該任務(wù)才執(zhí)行。可以使用二進(jìn)制信號量實現(xiàn)這種應(yīng)用:當(dāng)任務(wù)取信號量時,因為此時尚未發(fā)生特定事件,信號量為空,任務(wù)會進(jìn)入阻塞狀態(tài);當(dāng)外設(shè)需要維護(hù)時,觸發(fā)一個中斷服務(wù)例程,該中斷服務(wù)僅僅給出信號量(向隊列寫數(shù)據(jù))。任務(wù)只是取信號,并不需要歸還,中斷服務(wù)只是給信號。

任務(wù)的優(yōu)先級可以用于確保外設(shè)及時獲得維護(hù)。還可以使用隊列來代替二進(jìn)制信號量。中斷例程可以捕獲與外設(shè)事件相關(guān)的數(shù)據(jù)并將它發(fā)往任務(wù)的隊列。任務(wù)發(fā)現(xiàn)隊列數(shù)據(jù)有效時解除阻塞,如果需要,則進(jìn)行數(shù)據(jù)處理。第二種方案使得中斷執(zhí)行盡可能的短,其它處理過程可以在任務(wù)中實現(xiàn)。

注:中斷程序中決不可使用無“FromISR”結(jié)尾的API函數(shù)。

注:在大部分應(yīng)用場合,任務(wù)通知都可以代替二進(jìn)制信號量,并且速度更快、生成的代碼更少。

FreeRTOS實時操作系統(tǒng)信號量基礎(chǔ)知識點有哪些

圖1-1:中斷和任務(wù)之間同步---使用信號量

如圖1-1所示,程序開始運行時,信號量無效,因此任務(wù)阻塞在這個信號量下。一段時間后,一個中斷發(fā)生,在中斷服務(wù)程序中使用API函數(shù)xSemaphoreGiveFromISR()給出了一個信號,信號量變得有效。當(dāng)退出中斷服務(wù)程序后,執(zhí)行上下文切換,任務(wù)解除阻塞,使用API函數(shù)xSemaphoreTake()取走信號量并執(zhí)行任務(wù)。之后信號量變得無效,任務(wù)再次進(jìn)入阻塞。

3.計數(shù)信號量

二進(jìn)制信號量可以被認(rèn)為是長度為1的隊列,計數(shù)信號量則可以被認(rèn)為長度大于1的隊列。此外,信號量使用者不必關(guān)心存儲在隊列中的數(shù)據(jù),只需關(guān)心隊列是否為空。

通常計數(shù)信號量用于下面兩種事件:

計數(shù)事件:在這種場合下,每當(dāng)事件發(fā)生,事件處理程序?qū)⒔o出一個信號(信號量計數(shù)值增1),當(dāng)處理事件時,處理程序會取走信號量(信號量計數(shù)值減1)。因此,計數(shù)值是事件發(fā)生的數(shù)量和事件處理的數(shù)量差值。在這種情況下,計數(shù)信號量在創(chuàng)建時其值為0。

資源管理:這種用法下,計數(shù)值表示有效的資源數(shù)目。任務(wù)必須先獲取信號量才能獲取資源控制權(quán)。當(dāng)計數(shù)值減為零時表示沒有的資源。當(dāng)任務(wù)完成后,它會返還信號量---信號量計數(shù)值增加。在這種情況下,信號量創(chuàng)建時,計數(shù)值等于最大資源數(shù)目。

注:中斷程序中決不可使用無“FromISR”結(jié)尾的API函數(shù)。

注:在大部分應(yīng)用場合,任務(wù)通知都可以代替計數(shù)信號量,并且速度更快、生成的代碼更少。

4.互斥量

互斥量是一個包含優(yōu)先級繼承機(jī)制的二進(jìn)制信號量。用于實現(xiàn)同步(任務(wù)之間或者任務(wù)與中斷之間)的話,二進(jìn)制信號量是更好的選擇,互斥量用于簡單的互鎖。

用于互鎖的互斥量可以充當(dāng)保護(hù)資源的令牌。當(dāng)一個任務(wù)希望訪問某個資源時,它必須先獲取令牌。當(dāng)任務(wù)使用完資源后,必須還回令牌,以便其它任務(wù)可以訪問同一資源。

互斥量和信號量使用相同的API函數(shù),因此互斥量也允許指定一個阻塞時間。阻塞時間單位為系統(tǒng)節(jié)拍周期時間,數(shù)目表示獲取互斥量無效時最多處于阻塞狀態(tài)的系統(tǒng)節(jié)拍周期個數(shù)。

互斥量與二進(jìn)制信號量最大的不同是:互斥量具有優(yōu)先級繼承機(jī)制。也就是說,如果一個互斥量(令牌)正在被一個低優(yōu)先級任務(wù)使用,此時一個高優(yōu)先級企圖獲取這個互斥量,高優(yōu)先級任務(wù)會因為得不到互斥量而進(jìn)入阻塞狀態(tài),正在使用互斥量的低優(yōu)先級任務(wù)會臨時將自己的優(yōu)先級提升,提升后的優(yōu)先級與與進(jìn)入阻塞狀態(tài)的高優(yōu)先級任務(wù)相同。這個優(yōu)先級提升的過程叫做優(yōu)先級繼承。這個機(jī)制用于確保高優(yōu)先級任務(wù)進(jìn)入阻塞狀態(tài)的時間盡可能短,以及將已經(jīng)出現(xiàn)的“優(yōu)先級翻轉(zhuǎn)”影響降低到最小。

在很多場合中,某個硬件資源只有一個,當(dāng)?shù)蛢?yōu)先級任務(wù)占用該資源的時候,即便高優(yōu)先級任務(wù)也只能乖乖的等待低優(yōu)先級任務(wù)釋放資源。這里高優(yōu)先級任務(wù)無法運行而低優(yōu)先級任務(wù)可以運行的現(xiàn)象稱為“優(yōu)先級翻轉(zhuǎn)”。

為什么優(yōu)先級繼承能夠降低優(yōu)先級翻轉(zhuǎn)的影響呢?舉個例子,現(xiàn)在有任務(wù)A、任務(wù)B和任務(wù)C,三個任務(wù)的優(yōu)先級順序為任務(wù)C>任務(wù)B>任務(wù)A。任務(wù)A和任務(wù)C都要使用某一個硬件資源,并且當(dāng)前任務(wù)A占有該資源。

先看沒有優(yōu)先級繼承的情況:任務(wù)C也要使用該資源,但是此時任務(wù)A正在使用這個資源,因此任務(wù)C進(jìn)入阻塞,此時三個任務(wù)的優(yōu)先級順序沒有發(fā)生變化。在任務(wù)C進(jìn)入阻塞之后,某硬件產(chǎn)生了一次中斷,喚醒了一個事件,該事件可以解除任務(wù)B的阻塞狀態(tài)。在中斷結(jié)束后,因為任務(wù)B的優(yōu)先級是大于任務(wù)A的,所以任務(wù)B搶占任務(wù)A的CPU權(quán)限。那么任務(wù)C的阻塞時間就至少為:中斷處理時間+任務(wù)B的運行時間+任務(wù)A的運行時間。

再看有優(yōu)先級繼承的情況:任務(wù)C也要使用該資源,但是此時任務(wù)A正在使用這個資源,因此任務(wù)C進(jìn)入阻塞,此時由于優(yōu)先級A會繼承任務(wù)C的優(yōu)先級,三個任務(wù)的優(yōu)先級順序發(fā)生了變化,新的優(yōu)先級順序為:任務(wù)C=任務(wù)A>任務(wù)B。在任務(wù)C進(jìn)入阻塞之后,某硬件產(chǎn)生了一次中斷,喚醒了一個事件,該事件可以解除任務(wù)B的阻塞狀態(tài)。在中斷結(jié)束后,因為任務(wù)A的優(yōu)先級臨時被提高,大于任務(wù)B的優(yōu)先級,所以任務(wù)A繼續(xù)獲得CPU權(quán)限。任務(wù)A完成后,處于高優(yōu)先級的任務(wù)C會接管CPU。所以任務(wù)C的阻塞時間為:中斷處理時間+任務(wù)A的運行時間???,任務(wù)C的阻塞時間變小了,這就是優(yōu)先級繼承的優(yōu)勢。

優(yōu)先級繼承不能解決優(yōu)先級反轉(zhuǎn),只能將這種情況的影響降低到最小。硬實時系統(tǒng)在一開始設(shè)計時就要避免優(yōu)先級反轉(zhuǎn)發(fā)生。

FreeRTOS實時操作系統(tǒng)信號量基礎(chǔ)知識點有哪些

圖4-1 互斥量用于保護(hù)資源

如圖4-1所示,互斥量用來保護(hù)資源。為了訪問資源,任務(wù)必須先獲取互斥量。任務(wù)A想獲取資源,首先它使用API函數(shù)xSemaphoreTake()獲取信號量,成功獲取到信號量后,任務(wù)A就持有了互斥量,可以安全的訪問資源。期間任務(wù)B開始執(zhí)行,它也想訪問資源,任務(wù)B也要先獲得信號量,但是信號量此時是無效的,任務(wù)B進(jìn)入阻塞狀態(tài)。當(dāng)任務(wù)A執(zhí)行完成后,使用API函數(shù)xSemaphoreGive()釋放信號量。之后任務(wù)B解除阻塞,任務(wù)B使用API函數(shù)xSemaphoreTake()獲取并得到信號量,任務(wù)B可以訪問資源。

5.遞歸互斥量

已經(jīng)獲取遞歸互斥量的任務(wù)可以重復(fù)獲取該遞歸互斥量。使用xSemaphoreTakeRecursive()函數(shù)成功獲取幾次遞歸互斥量,就要使用xSemaphoreGiveRecursive()函數(shù)返還幾次,在此之前遞歸互斥量都處于無效狀態(tài)。比如,某個任務(wù)成功獲取5次遞歸互斥量,那么在它沒有返還5次該遞歸互斥量之前,這個互斥量對別的任務(wù)無效。

遞歸互斥量可以看成帶有優(yōu)先級繼承機(jī)制的信號量,獲取遞歸互斥量的任務(wù)在用完后必須返還。

互斥量不可以用在中斷服務(wù)程序中,這是因為:

互斥量具有優(yōu)先級繼承機(jī)制,只有在任務(wù)中獲取或給出互斥才有意義。

中斷不能因為等待互斥量而阻塞。

以上就是“FreeRTOS實時操作系統(tǒng)信號量基礎(chǔ)知識點有哪些”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學(xué)習(xí)更多的知識,請關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI