FreeRTOS 筆記之 臨界區及應用

2021-09-29 13:26:16 字數 2725 閱讀 6223

目錄

1. 臨界區概述

2. cortex-m核心快速關中斷指令

3. 關中斷

4. 開中斷

5. 進入/退出臨界段的巨集

6. 臨界段**的應用

臨界區指的是乙個訪問共用資源(例如:共用裝置或是共用儲存器)的程式片段,而這些共用資源又無法同時被多個執行緒訪問的特性。當有執行緒進入臨界區段時,其他執行緒或是程序必須等待(例如:bounded waiting 等待法),有一些同步的機制必須在臨界區段的進入點與離開點實現,以確保這些共用資源是被互斥獲得使用,例如:semaphore。只能被單一執行緒訪問的裝置,例如:印表機。

程序進入臨界區的排程原則是:

1、如果有若干程序要求進入空閒的臨界區,一次僅允許乙個程序進入。

2、任何時候,處於臨界區內的程序不可多於乙個。如已有程序進入自己的臨界區,則其它所有試圖進入臨界區的程序必須等待。

3、進入臨界區的程序要在有限時間內退出,以便其它程序能及時進入自己的臨界區。

4、如果程序不能進入自己的臨界區,則應讓出cpu,避免程序出現「忙等」現象。

臨界段用一句話概括就是一段在執行的時候不能被中斷的**段。

那麼什麼情況下臨界段會被打斷?乙個是系統排程,還有乙個就是外部中斷。在freertos,系統排程,最終也是產生pendsv中斷,在pendsv handler裡面實現任務的切換,所以還是可以歸結為中斷。既然這樣,freertos對臨界段的保護最終還是回到對中斷的開和關的控制。

為了快速地開關中斷, cortex-m核心專門設定了一條 cps 指令,有 4 種用法

primask和faultmast是cortex-m核心 裡面三個中斷遮蔽暫存器中的兩個,還有乙個是basepri,有關這三個暫存器的詳細用法見**

但是,在freertos中,對中斷的開和關是通過操作basepri暫存器來實現的,即大於等於basepri的值的中斷會被遮蔽,小於basepri的值的中斷則不會被遮蔽,不受freertos管理。使用者可以設定basepri的值來選擇性的給一些非常緊急的中斷留一條後路。

freertos關中斷的函式在portmacro.h中定義,分不帶返回值和帶返回值兩種

/* 不帶返回值的關中斷函式,不能巢狀,不能在中斷裡面使用 */

#define portdisable_interrupts() vportraisebasepri()

static portforce_inline void vportraisebasepri( void )

}

/* 帶返回值的關中斷函式,可以巢狀,可以在中斷裡面使用 */

#define portset_interrupt_mask_from_isr() ulportraisebasepri()

static portforce_inline uint32_t ulportraisebasepri( void )

return ulreturn;

}

freertos開中斷的函式在portmacro.h中定義

/* 不帶中斷保護的開中斷函式 */

#define portenable_interrupts() vportsetbasepri( 0 )

/* 帶中斷保護的開中斷函式 */

#define portclear_interrupt_mask_from_isr(x) vportsetbasepri(x)

static portforce_inline void vportsetbasepri( uint32_t ulbasepri )

}

進入和退出臨界段的巨集在task.h中定義

#define taskenter_critical()		portenter_critical()

#define taskenter_critical_from_isr() portset_interrupt_mask_from_isr()

#define taskexit_critical() portexit_critical()

#define taskexit_critical_from_isr( x ) portclear_interrupt_mask_from_isr( x )

進入和退出臨界段的巨集分中斷保護版本和非中斷版本,但最終都是通過開/關中斷來實現

#define portenter_critical()		vportentercritical();

#define portexit_critical() vportexitcritical();

void vportentercritical( void )

}void vportexitcritical( void )

}

在freertos中,對臨界段的保護出現在兩種場合,一種是在中斷場合一種是在非中斷場合,具體的應用見

/* 在中斷場合,臨界段可以巢狀 */

/* 在非中斷場合,臨界段不能巢狀 */

FreeRTOS 臨界區總結

當一名嵌入式開發人員從裸機開發切換到 基於 freertos 的開發後就要注意 中斷,資源競爭等等問題了。下面,總結一下 freertos 臨界區的知識及用法 1.應用程式使用臨界區 1.1 深入剖析的方法 1.2 使用方法 2.中斷函式中臨界區 2.1 深入剖析的方法 2.2 使用方法 void ...

FreeRTOS臨界區操作

進入臨界保護 支援巢狀 taskenter critical 退出臨界保護 支援巢狀 taskexit critical 中斷裡進入臨界保護 支援巢狀 taskenter critical from isr 中斷裡退出臨界保護 支援巢狀 taskexit critical from isr x 進入...

FreeRTOS臨界資源保護(臨界區保護)

臨界區未保護出現的異常 今天我們說說其中之一的原因 臨界資源未保護。我們先看個例子,假如有乙個5個節點單向鍊錶,如下結構 head 1 2 3 4 5 null 有一任務a在乙個單向鍊錶的2 3節點之間插入乙個新的2a節點,已經將2 2a,還未將2a 3,此時,鍊錶變為兩個未完整的部分,如下結構 h...