(STM32) NVIC (Nested vectored interrupt controller) 學習

NVIC 是 ARM Cortex-M 處理器的一部分。負責處理例外和中斷相關程序。

  • 允許巢狀中斷,在中斷時,還可以被中斷
  • Interrupt 可以自由設定,按照應用自己分配資源
  • 可以中斷遮罩,也就是可以停用某些中斷

優先權

在Cortex-M來說,數值越小代表優先權越高。

  • group priority (preempt priority)
  • subpriority

規則就是一個exception handler正在執行,其他例外發生時,如果group priority優先權比你高就可以插隊執行,如果跟你一樣或者比你低,就得乖乖等。

如果有多個相同優先權的例外處理正在 等待執行(Pending) ,那麼先比較subpriority,優先權較高的排在前面,如果還是一樣 Exception Nmber小的優先。

 

STM32中斷優先等級暫存器 (Interrupt Priority Registers)
STM32每個Interrupt Channel都擁有屬於自己的interrupt priority register, STM32中每個priority register是4個bit,這4-bits可以依據功能分成下面五組
NVIC_PriorityGroup_0 => 0 bits for pre-emption priority, 4 bits for subpriority  
NVIC_PriorityGroup_1 => 1 bits for pre-emption priority, 3 bits for subpriority  
NVIC_PriorityGroup_2 => 2 bits for pre-emption priority, 2 bits for subpriority  
NVIC_PriorityGroup_3 => 3 bits for pre-emption priority, 1 bits for subpriority  
NVIC_PriorityGroup_4 => 4 bits for pre-emption priority, 0 bits for subpriority  
NVIC_PriorityGroup
Preemption Priority
Subpriority
NVIC_PriorityGroup_0
0 (1 種設定)
0~15(16 種設定)
NVIC_PriorityGroup_1
0,1(2 種設定)
0~7(8 種設定)
NVIC_PriorityGroup_2
0,1,2,3 (4 種設定)
0,1,2,3(4 種設定)
NVIC_PriorityGroup_3
0,1,2,3,4,5,6,7 (8 種設定)
0,1(2 種設定)
NVIC_PriorityGroup_4
0~15(16 種設定)
0(1 種設定)

 

當我們在使用STM32的NVIC中斷時會發現,中斷的優先等級分成了preemption priority  與subpriority 兩種而這兩優先等級有甚麼不一樣:

1. Preemption Priority
    當中斷發生時,擁有較高Preemption priority=0的interrupt channel可以將較低preemptrion priority=1,2,3的interrupt chnannel中斷優先被處理。假如兩個interrupt channel擁有相同peemption priority,後到的interrupt event必須等到現有的中斷被處理完畢後才能被處理。
 
2. Subpriority 

     在兩個interrupt channel的preemption priority相同的前提下,如果兩個subpriority不同的interrupt event同時發生,則subpriority高的interrupt會先被處理,但是如果低優先等級的interrupt channel event 已經在執行,則不能被打斷,高subpriority的event必須等到現有的event被處理完才能被處理。

 

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x01;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x04;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);

NVIC_InitStruct.NVIC_IRQChannel = EXTI15_10_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x01;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x03;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);

以上範例如果先執行 EXTI0 在觸發 EXTI15_10,會優先執行 EXTI15_10

但如果 EXTI0 優先權比 EXTI15_10 高但是也觸發了,會等EXTI0執行完畢再執行EXTI15_10。

 

posted on 2019-05-28 00:26  OO程式猿  阅读(8082)  评论(0编辑  收藏  举报

导航