2012年12月7日

[Note] Cortex-M3 NVIC interrupt priority 基本觀念


     當我們在使用STM32中的NVIC中斷時會發現,中斷的優先等級分成了preemption priority (可搶奪優先等級)與subpriority(副優先等級)兩種,當我們在設定每一個interrupt channel的時候都必須設定這兩組數值。
     到底這兩優先等級有甚麼不一樣:

1. Preemption Priority
    當中斷發生時,擁有較高Preemption priority的interrupt channel可以將較低preemptrion priority的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被處理完才能被處理。

     
3. STM32中斷優先等級暫存器 (Interrupt Priority Registers)
  STM32每個Interrupt Channel都擁有屬於自己的interrupt priority register, STM32中每個priority register是4個bit(Cortex-M3中定義8-bits),這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  


pre-emption priority與subpriority共用這4bits暫存器位置,因此如果設定成NVIC_PriorityGroup_0,暫存器的值將會被辨識為subpriority必須注意到一件事情,那就是假使priority設定值超過了所選定Group中分配給他的位數,將會導致不可預期的錯誤。



下面用一個範例來說明:

NVIC_InitTypeDef NVIC_InitStructure;
// 定義Priority Group
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

一開始先定義了Priority Group為NVIC_PriorityGroup_2,因此其中會有2bits是給preemption priority,2bits給subpriority使用因此不論是preemption priority或者subpriority的值範圍都在0~3(2bits可以表是的最大數值),另外假使一個interrupt channel的preempriton prirority與其他所有的interrupt channel都不一樣,則這個interrupt channel的subpriority可以設為任意值。

沒有留言: