正確設置 FreeRTOS 與 STM32 的中斷優先級

裸機開發(非 RTOS)時,大多數 STM32 外設的中斷優先級通常不需要手動配置,原因如下:


? 裸機開發中默認中斷優先級行為

特點說明
默認中斷優先級為 0如果你不設置,STM32 HAL 默認設置所有外設中斷為 0(最高優先級)
沒有中斷搶占沖突因為沒有 RTOS 調度器,也不需要區分 ISR 和任務的優先級
ISR 不調用復雜調度邏輯不存在優先級違反 FreeRTOS API 限制的問題
常見 HAL 示例也是默認優先級STM32CubeMX 生成代碼通常直接 SetPriority(0,0)

🛠 舉個例子:裸機中 USART 初始化

HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn);

甚至你在裸機中 可以完全不調用 HAL_NVIC_SetPriority(),只調用 EnableIRQ() 也能正常運行,因為:

  • 啟動文件中(CMSIS)中斷默認優先級為 0
  • 沒有任務調度搶占的風險

🚨 但在使用 FreeRTOS 時必須配置

因為:

  • FreeRTOS 內核本身運行在中斷上下文中
  • ISR 優先級太高會 搶占調度器,而調度器不能被中斷
  • 使用了 FreeRTOS API 的 ISR 優先級必須 ≥ configMAX_SYSCALL_INTERRUPT_PRIORITY(默認 5

? 總結:裸機 vs RTOS 中斷優先級對比

項目裸機開發FreeRTOS 下
是否必須配置中斷優先級? 不需要? 必須配置
默認優先級0通常不夠安全
可否在 ISR 中調用復雜邏輯? 可以(不推薦)? 需要優先級保護
是否存在調度器限制? 無? 有嚴格限制

所以:

🟩 裸機時你基本可以不管中斷優先級,一切默認值也能跑
🟥 但用上 RTOS 后,中斷優先級配置就變成“必須做的事情”



要在 STM32(特別是使用 STM32 HAL 庫或 STM32duino)中正確配置 FreeRTOS 的中斷優先級宏,你需要理解兩部分:


? 正確設置 FreeRTOS 與 STM32 的中斷優先級宏

🔧 1. 關鍵宏定義

這些宏應該在 FreeRTOSConfig.h 中配置,主要是以下幾個:

#define configPRIO_BITS             __NVIC_PRIO_BITS  // STM32 定義的中斷優先級位數
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY      15
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5
#define configKERNEL_INTERRUPT_PRIORITY              ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
#define configMAX_SYSCALL_INTERRUPT_PRIORITY         ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )

📌 解釋各個宏:

宏名含義示例值(假設 4 bit)
configPRIO_BITSNVIC支持的優先級位數(STM32一般為4)4
configLIBRARY_LOWEST_INTERRUPT_PRIORITYHAL庫中最低優先級(數值大,優先級低)15
configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY允許使用 FreeRTOS API 的中斷最大優先級(數值小,優先級高)5
configKERNEL_INTERRUPT_PRIORITYFreeRTOS kernel 使用的實際中斷優先級值15 << (8 - 4) = 240
configMAX_SYSCALL_INTERRUPT_PRIORITY使用 FreeRTOS API 的中斷最大優先級值5 << (8 - 4) = 80

?? 必須遵守的規則

  • 所有 調用 FreeRTOS API 的中斷,它們的優先級必須設置為 等于或低于 configMAX_SYSCALL_INTERRUPT_PRIORITY(也就是數值大于或等于)
  • Kernel 的中斷優先級設置為最低(數值最大),防止搶占其他重要中斷。

? STM32 示例:如何在 FreeRTOSConfig.h 正確配置

假設你用的是 STM32F4(它是 4-bit 優先級):

#define configPRIO_BITS                          __NVIC_PRIO_BITS#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY         15
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY     5#define configKERNEL_INTERRUPT_PRIORITY      ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )

? STM32 中斷優先級設置對應修改(重要!)

你在使用 HAL 驅動時,還要確保中斷優先級設置正確,例如:

HAL_NVIC_SetPriority(USART1_IRQn, 6, 0); // 優先級 6 > 5,允許使用 FreeRTOS API

如果設置為 4 或更高(即數值更小,優先級更高):

HAL_NVIC_SetPriority(USART1_IRQn, 4, 0); // ? 錯誤!優先級太高,不能使用 FreeRTOS API

? 總結

要做的事是否必須
FreeRTOSConfig.h 中設置中斷優先級宏? 必須
避免高優先級中斷使用 FreeRTOS API(如 xQueueSendFromISR? 必須
查看芯片的 __NVIC_PRIO_BITS 定義? 建議
使用 HAL 配置中斷時遵守優先級規則? 必須

STM32 外設默認的 中斷優先級,如果你不手動設置 NVIC 優先級,會根據芯片啟動文件(CMSIS 啟動代碼)和 HAL 庫行為,遵循如下邏輯:


? 默認 NVIC 中斷優先級總結

情況默認優先級
手動調用 HAL_NVIC_SetPriority()你設置的值
未調用 HAL_NVIC_SetPriority()(也沒配置)默認為 0(即最高優先級)

? 所以:如果你不設置,STM32 中斷優先級就是 0(也就是“優先級最高”)


📍 示例:STM32 USB 默認優先級(未手動設置時)

例如,在 STM32F4 的 HAL_PCD_MspInit() 中:

HAL_NVIC_SetPriority(OTG_FS_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(OTG_FS_IRQn);

?? 所以默認優先級是 (preempt priority = 0, subpriority = 0) → 等效為 FreeRTOS 中最優先級


🚨 問題:和 FreeRTOS 沖突

FreeRTOS 要求調用其 API 的 ISR(中斷服務程序)必須使用較低優先級(優先級值 configMAX_SYSCALL_INTERRUPT_PRIORITY,通常是 5)。

而默認優先級是 0,會違反這個規則,會導致:

  • xQueueSendFromISRxTaskNotifyFromISR 等出錯
  • 系統斷言失敗(configASSERT
  • 出現 HardFault 或中斷嵌套異常

? 如何查看某個外設當前中斷優先級?

你可以在調試器或代碼中讀取:

uint32_t pri = NVIC_GetPriority(OTG_FS_IRQn);
printf("USB 中斷優先級: %lu\n", pri);

? 建議你總是手動設置中斷優先級

不要依賴默認值!

例如:

HAL_NVIC_SetPriority(OTG_FS_IRQn, 6, 0); // 比 FreeRTOS MAX_SYSCALL 中斷優先級(5)低,合法使用 FreeRTOS API
HAL_NVIC_EnableIRQ(OTG_FS_IRQn);

🔚 總結

問題默認行為
STM32 外設中斷默認優先級是多少?0(最高)
會影響 FreeRTOS 使用嗎?會。若你使用 FreeRTOS API,默認 0 會導致斷言失敗
應該設置嗎?? 必須設置,尤其是在 ISR 中用到了 FreeRTOS API

好的!以下是 STM32 常見外設的 推薦 NVIC 中斷優先級設置清單(在使用 FreeRTOS 的情況下,特別是涉及 xTaskNotifyFromISRxQueueSendFromISR 等 API 的時候)。


📌 優先級規則前提(以 4 個優先級位為例)

優先級數值優先級級別說明
0最高優先級? 不允許調用 FreeRTOS API
1 ~ 4高優先級? 不建議使用 FreeRTOS API
5 ~ 15合法范圍? 可使用 FreeRTOS API(建議 5~10)

? 所有 使用 FreeRTOS API 的中斷必須設置優先級為 ≥ configMAX_SYSCALL_INTERRUPT_PRIORITY(通常為 5


? 常見外設中斷推薦優先級表

外設類型中斷名稱(示例)推薦優先級(preempt)是否允許使用 FreeRTOS API說明
USB FS/HSOTG_FS_IRQn, USB_LP_CAN_RX0_IRQn6? 是TinyUSB 常用
USART / UARTUSARTx_IRQn67? 是接收中斷中常用隊列、通知
TIM 定時器TIMx_IRQn78? 是軟件定時器事件、任務喚醒等
EXTI 外部中斷EXTI0_IRQn, EXTIx_IRQn6 ~ 10? 是按鍵、外部觸發事件
DMADMAx_Streamx_IRQn6 ~ 8? 是用于通知任務數據到位
I2C / SPII2Cx_EV_IRQn, SPIx_IRQn6 ~ 10? 是通信完成后喚醒任務
ADC / DACADCx_IRQn8 ~ 12? 是可用于數據采樣后任務處理
看門狗 / 硬件錯誤WWDG_IRQn, HardFault_IRQn0 ~ 2? 否不應使用 FreeRTOS API

📌 示例配置代碼(推薦)

// USB
HAL_NVIC_SetPriority(OTG_FS_IRQn, 6, 0);
HAL_NVIC_EnableIRQ(OTG_FS_IRQn);// USART
HAL_NVIC_SetPriority(USART1_IRQn, 7, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn);// TIM 定時器
HAL_NVIC_SetPriority(TIM2_IRQn, 8, 0);
HAL_NVIC_EnableIRQ(TIM2_IRQn);

?? 注意:STM32 優先級是“數值越小,優先級越高”

所以:

  • 0 是最高優先級(? 禁止用于 FreeRTOS ISR API)
  • 15 是最低優先級

? 建議配置總結

類型推薦優先級范圍(Preempt)舉例
非實時,允許用 FreeRTOS API5 ~ 10USB / USART / TIM
高實時需求 ISR(不用 RTOS API)0 ~ 4ADC / HardFault / 高速通信
RTOS 調度器自身通常為 15自動配置

在 FreeRTOS 中,調度器本身并不是一個中斷或任務,它運行在 CPU空閑時 或由 SysTick 和 PendSV 中斷驅動上下文切換。但我們可以從以下幾個角度來理解你問的“調度器優先級”:


🔧 1. 調度相關中斷優先級

FreeRTOS 使用兩個關鍵中斷來實現調度:

中斷作用推薦優先級說明
SysTick_IRQn觸發時間片中斷,驅動 tick 增加最低優先級(如 15系統節拍來源
PendSV_IRQn實現任務切換(上下文切換)最低優先級(如 15必須低于其他中斷

? 所以我們通常手動或由 FreeRTOS 內部將這兩個設置為:

NVIC_SetPriority(PendSV_IRQn, 15);
NVIC_SetPriority(SysTick_IRQn, 15);

📌 它們必須設為最低優先級,否則會干擾中斷服務。


?? 2. FreeRTOS 內核中配置項解釋

FreeRTOSConfig.h 中,你配置了內核調度相關的“優先級窗口”,用于約束允許調用 FreeRTOS API 的中斷優先級范圍:

#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY         15
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY     5

這意味著:

  • 所有使用 FreeRTOS API 的中斷優先級 必須為 5~15(數值越大優先級越低)
  • PendSV_IRQnSysTick_IRQn 會設置為 configKERNEL_INTERRUPT_PRIORITY(通常為 15

? 3. FreeRTOS 任務優先級

這個和 NVIC 中斷優先級是兩個不同的體系

概念范圍數值越大優先級
任務優先級0 ~ configMAX_PRIORITIES - 1越高(更優先被調度)
中斷優先級數值越小優先級越高(STM32)越高(會搶占其他中斷)

例如:

vTaskCreate(..., uxPriority = 5, ...);  // FreeRTOS 任務優先級為 5(調度優先)

🧠 總結:FreeRTOS 調度器相關優先級一覽

項目優先級值(通常)優先級說明
PendSV_IRQn15最低中斷優先級,切換任務用,必須最低
SysTick_IRQn15時鐘節拍中斷,驅動調度器 tick
configKERNEL_INTERRUPT_PRIORITY15內核運行的最低安全中斷
configMAX_SYSCALL_INTERRUPT_PRIORITY5(可調)可使用 FreeRTOS API 的最高優先級
FreeRTOS 任務優先級0 ~ configMAX_PRIORITIES-1數值越大越優先執行(與中斷無關)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/87860.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/87860.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/87860.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

EasyExcel之SheetWriteHandler:解鎖Excel寫入的高階玩法

引言在 EasyExcel 強大的功能體系中&#xff0c;SheetWriteHandler 接口是一個關鍵的組成部分。它允許開發者在寫入 Excel 的 Sheet 時進行自定義處理&#xff0c;為實現各種復雜的業務需求提供了強大的支持。通過深入了解和運用 SheetWriteHandler 接口&#xff0c;我們能夠更…

Python單例模式魔法方法or屬性

1.單例模式概念定義:單例模式(Singleton Pattern)是一種創建型設計模式&#xff0c;它確保一個類只能有一個實例&#xff0c;并提供一個全局訪問點來獲取該實例。這種模式在需要控制資源訪問、配置管理或協調系統操作時特別有用。核心特點:私有構造函數&#xff1a;防止外部通過…

【Kubernetes系列】Kubernetes 資源請求(Requests)

博客目錄 引言一、資源請求的基本概念1.1 什么是資源請求1.2 請求與限制的區別 二、CPU 請求的深入解析2.1 CPU 請求的單位與含義2.2 CPU 請求的調度影響2.3 CPU 請求與限制的關系 三、內存請求的深入解析3.1 內存請求的單位與含義3.2 內存請求的調度影響3.3 內存請求的特殊性 …

大型語言模型中的自動化思維鏈提示

摘要 大型語言模型&#xff08;LLMs&#xff09;能夠通過生成中間推理步驟來執行復雜的推理任務。為提示演示提供這些步驟的過程被稱為思維鏈&#xff08;CoT&#xff09;提示。CoT提示有兩種主要范式。一種使用簡單的提示語&#xff0c;如“讓我們一步一步思考”&#xff0c;…

Private Set Generation with Discriminative Information(2211.04446v1)

1. 遇到什么問題&#xff0c;解決了什么遇到的問題現有差分隱私生成模型受限于高維數據分布建模的復雜性&#xff0c;合成樣本實用性不足。深度生成模型訓練依賴大量數據&#xff0c;加入隱私約束后更難優化&#xff0c;且不保證下游任務&#xff08;如分類&#xff09;的最優解…

C++編程語言入門指南

一、C語言概述 C是由丹麥計算機科學家Bjarne Stroustrup于1979年在貝爾實驗室開發的一種靜態類型、編譯式、通用型編程語言。最初被稱為"C with Classes"(帶類的C)&#xff0c;1983年更名為C。它既具有高級語言的抽象特性&#xff0c;又保留了底層硬件操作能力&…

ZED相機與Foxglove集成:加速機器人視覺調試效率的實用方案

隨著機器人技術的發展&#xff0c;實時視覺數據流的高效傳輸和可視化成為提升系統性能的重要因素。通過ZED相機&#xff08;包括ZED 2i和ZED X&#xff09;與Foxglove Studio平臺的結合&#xff0c;開發者能夠輕松訪問高質量的2D圖像、深度圖和點云數據&#xff0c;從而顯著提高…

目標檢測新紀元:DETR到Mamba實戰解析

&#x1f680;【實戰分享】目標檢測的“后 DE?”時代&#xff1a;DETR/DINO/RT-DETR及新型骨干網絡探索&#xff08;含示例代碼&#xff09; 目標檢測從 YOLO、Faster R-CNN 到 Transformer 結構的 DETR&#xff0c;再到 DINO、RT-DETR&#xff0c;近兩年出現了許多新趨勢&am…

【IOS】XCode創建firstapp并運行(成為IOS開發者)

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 這篇文章主要介紹XCode創建firstapp并運行 學其所用&#xff0c;用其所學。——梁啟超 歡迎來到我的博客&#xff0c;一起學習&#xff0c;共同進步。 喜歡的朋友可以關注一下&#xff0c;下次更新不迷路…

class類和style內聯樣式的綁定 + 事件處理 + uniapp創建自定義頁面模板

目錄 一.class類的綁定 1.靜態編寫 2.動態編寫 二.style內聯樣式的綁定 三.事件處理 1.案例1 2.案例2 四.uniapp創建自定義頁面模板 1.為什么要這么做&#xff1f; 2.步驟 ①打開新建頁面的界面 ②在彈出的目錄下&#xff0c;新建模板文件 ③用HBuilderX打開該模板…

android 卡頓和丟幀區別

Android 卡頓&#xff08;Jank&#xff09;與丟幀&#xff08;Frame Drop&#xff09;的核心區別在于問題本質與用戶感知&#xff0c;以下是分層解析&#xff1a; ? 一、本質差異 維度卡頓&#xff08;Jank&#xff09;丟幀&#xff08;Frame Drop&#xff09;定義用戶可感知…

【python實用小腳本-125】基于 Python 的 Gmail 郵件發送工具:實現高效郵件自動化

引言 在現代辦公和開發環境中&#xff0c;郵件通信是一種重要的溝通方式。自動化發送郵件可以大大提高工作效率&#xff0c;例如發送通知、報告或文件。本文將介紹一個基于 Python 的 Gmail 郵件發送工具&#xff0c;它能夠通過 Gmail 的 SMTP 服務器發送郵件&#xff0c;并支持…

gateway斷言配置詳解

一、Predicate - 斷? 1、簡單用法 spring:cloud:gateway:routes:- id: after_routeuri: https://example.orgpredicates:- After2017-01-20T17:42:47.789-07:00[America/Denver] 2、自定義斷言 新建類VipRoutePredicateFactory&#xff0c;注意VipRoutePredicateFactory名字…

基于大模型的尿毒癥全流程預測與診療方案研究報告

目錄 一、引言 1.1 研究背景與意義 1.2 研究目的與方法 1.3 國內外研究現狀 二、尿毒癥相關理論基礎 2.1 尿毒癥的定義、病因與發病機制 2.2 尿毒癥的癥狀與診斷標準 2.3 尿毒癥的治療方法概述 三、大模型技術原理與應用 3.1 大模型的基本概念與發展歷程 3.2 大模型…

裸金屬服務器租用平臺-青蛙云

企業對服務器性能與靈活性的要求與日俱增。青蛙云M-啟強裸金屬服務器租用平臺應運而生&#xff0c;為企業提供了一種兼具物理機性能和云計算彈性的解決方案。裸金屬服務器租用平臺的優勢?(一)高配性能&#xff0c;無虛擬化開銷?裸金屬服務器直接運行在物理硬件之上&#xff0…

[Terence Tao訪談] AlphaProof系統 | AI嗅覺 | 研究生學習 | 龐加萊猜想(高維) | 復雜問題簡單化

玩這些有趣的東西。通常情況下什么也得不到&#xff0c;你必須學會說&#xff1a;“好吧&#xff0c;再試一次&#xff0c;什么都沒發生&#xff0c;我會繼續前進。” DeepMind的AlphaProof系統 Q&#xff1a;DeepMind的AlphaProof系統是通過強化學習訓練的&#xff0c;使用的…

Aseprite工具入門教程4之動畫導入Unity

1、時間軸功能 &#xff08;1&#xff09;眼睛圖標 顯示/隱藏圖層圖層隱藏時無法繪制 &#xff08;2&#xff09;鎖定圖標 鎖定后無法移動或編輯圖層防止意外在錯誤圖層上繪制 &#xff08;3&#xff09;單元格圖標 兩個點代表幀分開&#xff0c;一個橢圓代表幀統一。分開就…

移動硬盤頻繁提示格式化?解決異常故障的正確方法

移動硬盤作為數據存儲的重要工具&#xff0c;不少人都習慣將照片、文檔、項目資料甚至整臺電腦的備份都放在里面。但有時&#xff0c;一件令人頭疼的事悄然發生&#xff1a; 插上硬盤&#xff0c;系統卻突然提示&#xff1a;“使用驅動器中的光盤之前需要將其格式化。是否要將…

Java泛型筆記

1 為什么需要泛型 Java5之前&#xff0c;是沒有泛型的。通過兩段代碼我們就可以知道為何我們需要泛型 public int addInt(int a, int b) {return a b; }public double addDouble(double a, double b) {return a b; } 實際開發中&#xff0c;經常有數值類型求和的需求&…

mysql 圖形化界面工具 DataGrip 安裝與配置

安裝地址&#xff1a; Download DataGrip: Cross-Platform IDE for Databases & SQLhttps://www.jetbrains.com/datagrip/download/?sectionwindows 添加數據源&#xff1a; 下載驅動文件&#xff1a;直接點擊下載即可 點擊測試連接&#xff1a;成功后點擊確定 顯示所有數…