FreeRTOS 中斷優(yōu)先級配置(重要)
NVIC 基礎(chǔ)知識
????對于 M3 和 M4 內(nèi)核的 MCU,每個中斷的優(yōu)先級都是用寄存器中的 8 位設(shè)置的。
????8 位的話就可以 設(shè)置 2^8 = 256 級中斷,實際中用不了這么多,所以芯片廠商根據(jù)自己生產(chǎn)的芯片做出了調(diào)整。
????比如 ST 的 STM32F1xx 和 F4xx 只使用了這個 8 位中的高四位[7:4],低四位取零,這樣 2^4=16,只能表示 16 級中斷嵌套。
STM32F1xx 和 F4xx 都是只使用了這個 8 位寄存器的高四位[7:4]

????STM32 支持 5 種優(yōu)先級分組,系統(tǒng)上電復(fù)位后,默認使用的是優(yōu)先級分組 0,也就是沒有搶占式優(yōu)先級,只有子優(yōu)先級
????1.具有高搶占式優(yōu)先級的中斷可以在具有低搶占式優(yōu)先級的中斷服務(wù)程序執(zhí)行過程中被響應(yīng),即中斷嵌套,或者說高搶占式優(yōu)先級的中斷可以搶占低搶占式優(yōu)先級的中斷的執(zhí)行。?
????2.在搶占式優(yōu)先級相同的情況下,有幾個子優(yōu)先級不同的中斷同時到來,那么高子優(yōu)先級的中斷優(yōu) 先被響應(yīng)。?
????3.在搶占式優(yōu)先級相同的情況下,如果有低子優(yōu)先級中斷正在執(zhí)行,高子優(yōu)先級的中斷要等待已被響應(yīng)的低子優(yōu)先級中斷執(zhí)行結(jié)束后才能得到響應(yīng),即子優(yōu)先級不支持中斷嵌套。?
????4.?Reset、NMI、Hard Fault 優(yōu)先級為負數(shù),高于普通中斷優(yōu)先級,且優(yōu)先級不可配置。
?????5.?系統(tǒng)中斷(比如:PendSV,SVC,SysTick)是不是一 定比外部中斷(比如 SPI,USART)要高?,答案:不是的,它們是在同一個 NVIC 下面設(shè)置的。
配置搶占優(yōu)先級和子優(yōu)先級,他們合并成的 4bit 數(shù)字的數(shù)值越小,優(yōu)先級越高
使用 FreeRTOS 時如何配置外設(shè) NVIC
????官方強烈建議將 Cortex-M3 內(nèi)核和 Cortex-M4 內(nèi)核?的 NVIC 優(yōu)先級分組設(shè)置為 4,
(注意:一旦初始化好 NVIC 的優(yōu)先級分組后,切不可以在應(yīng)用中再次更改。)?
????設(shè)置 NVIC 的優(yōu)先級分組為 4 表示支持 0-15 級搶占優(yōu)先級(注意,0-15 級是 16 個級別,包含 0 級),不支持子優(yōu)先級
反映在 STM32 標準庫的配置上就是如下:
FreeRTOS 配置選項中 NVIC 相關(guān)配置
◆ #define configPRIO_BITS ????4
????此宏定義用于配置 STM32 的 8 位優(yōu)先級設(shè)置寄存器實際使用的位數(shù)。
◆ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ????0x0f
????此宏定義是用來配置 FreeRTOS 用到的 SysTick 中斷和 PendSV 中斷的優(yōu)先級。
????在 NVIC 分組設(shè)置為 4 的情況下,此宏定義的范圍就是 0-15,即專門配置搶占優(yōu)先級。這里配置為了 0x0f,即 SysTick 和 PendSV 都是配置為了最低優(yōu)先級,實際項目中也建議大家配置最低優(yōu)先級即可。?
◆ #define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY???? 0x01
????此宏定義比較重要,定義了受 FreeRTOS 管理的最高優(yōu)先級中斷。
????簡單的說就是允許用戶在這個中斷服務(wù)程序里面調(diào)用 FreeRTOS 的 API 的最高優(yōu)先級。
設(shè)置 NVIC 的優(yōu)先級分組為 4 的情況下。配置 此宏定義為 0x01 表示用戶可以在搶占式優(yōu)先級為1到 15 的中斷里面調(diào)用 FreeRTOS 的 API 函數(shù),搶占式優(yōu)先級為 0 的中斷里面是不允許調(diào)用的。
不受 FreeRTOS 管理中斷的深入討論
????中斷延遲時間是衡量 RTOS 實時操作系統(tǒng)的一項重要指標,那什么又是中斷延遲呢?
????從中斷觸發(fā)到執(zhí)行中斷服務(wù)程序的第一條指令這段時間就是中斷延遲時間。
FreeRTOS 內(nèi)核源碼中有多處開關(guān)全局中斷的地方,這些開關(guān)全局中斷會加大中斷延遲時間。
????比如在源碼的某個地方關(guān)閉了全局中斷,但是此時有外部中斷觸發(fā),這個中斷的服務(wù)程序就需要等到再次開啟全局中斷后才可以得到執(zhí)行。開關(guān)中斷之間的時間越長,中斷延遲時間就越大,這樣極其影響系統(tǒng)的實時性。 如果這是一個緊急的中斷事件,得不到及時執(zhí)行的話,后果是可想而知的。
????針對這種情況,F(xiàn)reeRTOS 就專門做了一種新的開關(guān)中斷實現(xiàn)機制。
????關(guān)閉中斷時僅關(guān)閉受 FreeRTOS 管理的中斷,不受 FreeRTOS 管理的中斷不關(guān)閉,這些不受管理的中斷都是高優(yōu)先級的中斷,用戶可以在這些中斷里面加入需要實時響應(yīng)的程序。FreeRTOS 能夠?qū)崿F(xiàn)這種功能的奧秘就在于 FreeRTOS 開關(guān)中斷 使用的是寄存器 basepri

uCOS 這種使用的是 primask

????比如配置寄存器 basepri 的數(shù)值為 16,所有優(yōu)先級數(shù)值大于等于 16 的中斷都會被關(guān)閉,優(yōu)先級數(shù)值小于 16 的中斷不會被關(guān)閉。對寄存器 basepri 寄存器 賦值 0,那么被關(guān)閉的中斷會被打開。這個就是 FreeRTOS 開關(guān)中斷的實現(xiàn)方案。
FreeRTOS 任務(wù)優(yōu)先級修改及其分配方案
下面對 FreeRTOS 優(yōu)先級相關(guān)的幾個重要知識點進行下說明,這些知識點在以后的使用中務(wù)必要掌握牢固。
????◆ FreeRTOS 中任務(wù)的最高優(yōu)先級是通過 FreeRTOSConfig.h 文件中的 configMAX_PRIORITIES 進行配置的,用戶實際可以使用的優(yōu)先級范圍是 0 到 configMAX_PRIORITIES – 1。
????比如我們配置此宏定義為 5,那么用戶可以使用的優(yōu)先級號是 0,1,2,3,4,不包含 5。
◆ 用戶配置任務(wù)的優(yōu)先級數(shù)值越小,那么此任務(wù)的優(yōu)先級越低,空閑任務(wù)的優(yōu)先級是 0。
◆ 建議用戶配置宏定義 configMAX_PRIORITIES 的最大值不要超過 32,即用戶任務(wù)可以使用的優(yōu)先級范圍是0到31。
◆ 如果用戶在 FreeRTOSConfig.h 文件中配置宏定義 configUSE_TIME_SLICING 為 1,或者沒有配置此宏定義,時間片調(diào)度都是使能的。
????另外,只要芯片資源允許,可以配置任意多個同優(yōu)先級任務(wù)。?
(備注:沒有定義 configUSE_TIME_SLICING,也能使用時間片調(diào)度是因為此宏定義默認已經(jīng)在 FreeRTOS.h 文件中使能)
◆ FreeRTOS 中處于運行狀態(tài)的任務(wù)永遠是當前能夠運行的最高優(yōu)先級任務(wù)。
任務(wù)優(yōu)先級分配方案

◆ IRQ 任務(wù):IRQ 任務(wù)是指通過中斷服務(wù)程序進行觸發(fā)的任務(wù),此類任務(wù)應(yīng)該設(shè)置為所有任務(wù)里面優(yōu)先級最高的。?
◆ 高優(yōu)先級后臺任務(wù):比如按鍵檢測,觸摸檢測,USB 消息處理,串口消息處理等,都可以歸為這一類任務(wù)。?
◆ 低優(yōu)先級的時間片調(diào)度任務(wù):比如 LED 數(shù)碼管的顯示等不需要實時執(zhí)行的都可以歸為這一類任務(wù)。
????實際應(yīng)用中用戶不必拘泥于將這些任務(wù)都設(shè)置為同優(yōu)先級任務(wù),可以設(shè)置多個優(yōu)先級,只需注意這類任務(wù)不需要高實時性。
◆ 空閑任務(wù):空閑任務(wù)是系統(tǒng)任務(wù)。?
◆ 特別注意:IRQ 任務(wù)和高優(yōu)先級任務(wù)必須設(shè)置為阻塞式(調(diào)用消息等待或者延遲等函數(shù)即可),只有這樣,高優(yōu)先級任務(wù)才會釋放 CPU 的使用權(quán),從而低優(yōu)先級任務(wù)才有機會得到執(zhí)行。?
這里的優(yōu)先級分配方案是推薦的一種方式,實際項目也可以不采用這種方法。調(diào)試出適合項目需求的才是最好的。
中斷優(yōu)先級和任務(wù)優(yōu)先級區(qū)別
????簡單的說,兩者之間沒有任何關(guān)系,不管中斷的優(yōu)先級是多少,中斷的優(yōu)先級永遠高于任何任務(wù)的優(yōu)先級,即任務(wù)在執(zhí)行的過程中,中斷來了就開始執(zhí)行中斷服務(wù)程序。 另外對于 STM32F103,F(xiàn)407 和 F429 來說,中斷優(yōu)先級的數(shù)值越小,優(yōu)先級越高。而 FreeRTOS 的任務(wù)優(yōu)先級是,任務(wù)優(yōu)先級數(shù)值越小,任務(wù)優(yōu)先級越低。
任務(wù)優(yōu)先級修改
◆ vTaskPrioritySet ()
◆ 第 1 個參數(shù)是任務(wù)句柄,用于區(qū)分不同的任務(wù)。?
◆ 第 2 個參數(shù)是給任務(wù)配置的新優(yōu)先級。
使用這個函數(shù)要注意以下問題:
????1. 使用此函數(shù)需要在 FreeRTOSConfig.h 配置文件中配置如下宏定義為 1?
????#define INCLUDE_vTaskPrioritySet ????1?
????2. 如果第二個參數(shù)里面填的是 NULL,即數(shù)值 0 的話,那么配置的就是當前正在執(zhí)行的任務(wù)。?
????3. 如果被修改的任務(wù)的優(yōu)先級,修改后高于正在執(zhí)行的任務(wù),將執(zhí)行任務(wù)切換,切換到修改好的高優(yōu)先級任務(wù)。?
????4. 第二個參數(shù)數(shù)值不可大于等于 FreeRTOSConfig.h 文件中的宏定義:?
????#define configMAX_PRIORITIES 配置的數(shù)值。
任務(wù)優(yōu)先級獲取
vTaskPriorityGet ()
使用這個函數(shù)要注意以下問題:?
????1. 使用此函數(shù)需要在 FreeRTOSConfig.h 配置文件中配置如下宏定義為 ????1?
????#define INCLUDE_vTaskPriorityGet 1?
????2. 如果第二個參數(shù)里面填的是 NULL,即數(shù)值 0 的話,那么獲取的優(yōu)先級就是當前正在執(zhí)行的任務(wù)。