精華總結:
中斷優先級0為最高,任務優先級0為最低
中斷優先級分組中為方便rtos管理4bit全部設置成搶占優先級
32單片機的中斷管理是由3個寄存器完成(名字忽略,具體功能忽略),三個寄存器都是32bit,通過移位可操作設置寄存器上的bit位,比如可設置pendsv中斷和systick中斷優先級
最終,pendsv與systick被設置成15,pendsv與systick切換任務的時候不會影響到其它中斷的觸發(比如外部中斷)
上面三個寄存器是設置中斷優先級;還有三個寄存器用于屏蔽中斷,freertos使用了寄存器BASEPRI用于中斷屏蔽,為0x50代表關閉(也可以說屏蔽)5-15優先級的中斷,為0代表不關閉(屏蔽)任何中斷(就是這個寄存器規定了freertos只能控制5-15優先級的中斷),如果為0x60,則就是6-15
1、中斷優先級分組全部設置成搶占優先級->是為了方便freertos管理中斷
即:HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
2、你的中斷優先級設置必須是5-15(當然也可以為0-4,但這樣不受控了)
3、freertos只能控制5-15優先級的中斷
4、0-4的中斷因為rtos不可控,所以禁止0-4的中斷調用rtos的api函數,因此設置搶占優先級必須≥5才行,如果你設置成了4則rtos控制不了則無法控制別人搶占你或者你搶占別人
什么是中斷?
簡介:讓CPU打斷正常運行的程序,轉而去處理緊急的事件(程序),就叫中斷
例:
中斷執行機制,可簡單概括為三步:
中斷優先級分組設置
ARM Cortex-M 使用了 8 位寬的寄存器來配置中斷的優先等級,這個寄存器就
是中斷優先級配置寄存器,因此最大中斷的優先級配置范圍位 0~255。但是芯片廠商一般用不
完這些資源,對于 STM32,只用到了中斷優先級配置寄存器的高 4 位[7:4],低四位[3:0]取零處
理,因此 STM32 提供了最大 2^4=16 級的中斷優先等級
中斷優先級配置寄存器的值與對應的優先等級成反比,即中斷優先級配置寄存器的值越小,
中斷的優先等級越高。
STM32 的中斷優先級可以分為搶占優先級和子優先級,搶占優先級和子優先級的區別如下:
搶占優先級: 搶占優先級高的中斷可以打斷正在執行但搶占優先級低的中斷,即中斷嵌套。
子優先級: 搶占優先級相同時,子優先級高的中斷不能打斷正在執行但子優先級低的中的
中斷,即子優先級不支持中斷嵌套。??
STM32 中每個中斷的優先級就由搶占優先級和子優先級共同組成,使用中斷優先級配置寄
存器的高 4 位來配置搶占優先級和子優先級,那么中斷優先級配置寄存器的高 4 位是如何分配
設置搶占優先級和子優先級的呢?
一共有 5 種分配方式,對應著中斷優先級分組的 5 個組
通過調用函數HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4)即可完成設置
老生常談,FreeRTOS只用分組4,因為這樣方便打斷,不用考慮子優先級了
中斷優先級0為最高,任務優先級0為最低
中斷相關寄存器
三個系統中斷優先級配置寄存器:
分別為 SHPR1、 SHPR2、 SHPR3
SHPR1寄存器地址:0xE000ED18
SHPR2寄存器地址:0xE000ED1C
SHPR3寄存器地址:0xE000ED20
表出自:《Cortex M3權威指南(中文)》第286頁
1. SHPR1
SHPR1 寄存器的地址為 0xE000ED18, 用于配置 MemManage、 BusFault、 UsageFault 的中
斷優先級, 各比特位的功能描述如下表所示:
2. SHPR2
SHPR2 寄存器的地址為 0xE000ED1C,用于配置 SVCall 的中斷優先級, 各比特位的功能
描述如下表所示:
3. SHPR3
SHPR3 寄存器的地址為 0xE000ED20,用于配置 PendSV、 SysTick 的中斷優先級, 各比特
位的功能描述如下表所示:
FreeRTOS 在配置 PendSV 和 SysTick 中斷優先級的時,就使用到了 SHPR3 寄存器
FreeRTOS 如何配置 PendSV 和 SysTick 中斷優先級:
PendSV和SysTick設置最低優先級
設置最低:保證系統任務切換不會阻塞系統其他中斷的響應
三個中斷屏蔽寄存器:
分別為 PRIMASK、 FAULTMASK 和BASEPRI
FreeRTOS所使用的中斷管理就是利用的BASEPRI這個寄存器
BASEPRI:屏蔽優先級低于某一個閾值的中斷
比如: BASEPRI設置為0x50,代表中斷優先級在5~15內的均被屏蔽,0~4的中斷優先級正常執行
建議參考知識庫中:GPT對話知識庫——FreeRTOS中寄存器BASEPRI的作用
BASEPRI:屏蔽優先級低于某一個閾值的中斷,當設置為0時,則不關閉任何中斷
關中斷程序示例:
#define portDISABLE_INTERRUPTS()vPortRaiseBASEPRI()static portFORCE_INLINE void vPortRaiseBASEPRI( void ){uint32_t ulNewBASEPRI = configMAX_SYSCALL_INTERRUPT_PRIORITY;__asm{msr basepri, ulNewBASEPRIdsbisb}}#define configMAX_SYSCALL_INTERRUPT_PRIORITY( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY5/* FreeRTOS可管理的最高中斷優先級 */
中斷優先級在5 ~ 15的全部被關閉
開中斷程序示例:
#define portENABLE_INTERRUPTS()vPortSetBASEPRI( 0 )static portFORCE_INLINE void vPortSetBASEPRI( uint32_t ulBASEPRI ){__asm{msr basepri, ulBASEPRI}}
FreeRTOS中斷管理就是利用BASEPRI寄存器實現的
當BASEPRI設置為0x50時:
在中斷服務函數中調度FreeRTOS的API函數需注意:
1、中斷服務函數的優先級需在FreeRTOS所管理的范圍內
2、在中斷服務函數里邊需調用FreeRTOS的API函數,必須使用帶“FromISR”后綴的函數
參考鏈接:
https://blog.csdn.net/weixin_44639540/article/details/129007015