2009-09-24 10:40 AM
System Handler and USART Interrupts in the NVIC
2011-05-17 04:21 AM
Hi,
I've been going through the forum for an answer to the following question but was unable to find it... I would appreciate it if someone could help me out. Q) I am trying to understand the difference between the NVIC_SystemHandlerPriorityConfig and the NVIC_PriorityGroupConfig. As I understand, the STM32 has 4 bits for external interrupts. Which is 16 priority levels (Preemption + Subpriority) and can be manipulated via NVIC_PriorityGroupConfig function. The NVIC_SystemHandlerPriorityConfig will set the System Handlers Priority Register [31:24].Code:
// 0xE000ED20 - SysTick (PRI_15) NVIC_SystemHandlerPriorityConfig(SystemHandler_SysTick, 0, 0); Application Interrupt and Reset Control Register [10:8]Priority Group 7 -> NVIC_PriorityGroup_0 [0 bits preemption, 4 bits subpriority] Priority Group 6 -> NVIC_PriorityGroup_1 [1 bits preemption, 3 bits subpriority] Priority Group 5 -> NVIC_PriorityGroup_2 [2 bits preemption, 2 bits subpriority] Priority Group 4 -> NVIC_PriorityGroup_3 [3 bits preemption, 1 bits subpriority] Priority Group 3 -> NVIC_PriorityGroup_4 [4 bits preemption, 0 bits subpriority] The System Handler SysTick has 8 bits for priority settings, and the external interrupts has 4 bits. How are they related?Code:
// Resets the NVIC registers to their default reset value NVIC_DeInit(); // Resets the SCB registers to their default reset value NVIC_SCBDeInit(); // Configure the Priority Grouping with 2 bits for preemption and 2 bits for subpriority NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // Enable SysTick System interrupt with Preemption Priority 0 and SubPriority as 0 NVIC_SystemHandlerPriorityConfig(SystemHandler_SysTick, 0, 0); // Enable USB Global interrupt with Preemption Priority 0 and SubPriority as 1 NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN_RX0_IRQChannel; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); // Enable USART1 Global interrupt with Preemption Priority 0 and SubPriority as 2 NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQChannel; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); // Enable USART2 Global interrupt with Preemption Priority 0 and SubPriority as 1 NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQChannel; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); SysTick has the highest priority and USART2 has the lowest. If SysTick and USB_LP occurs at the sametime, SysTick is selected. If USART1 and USART2 occurs at the sametime, USART1 is selected. If SysTick and USART1 occurs, SysTick is selected. Have I understood this correctly or I messed it up? :p Thanks for your comments. -Mad2011-05-17 04:21 AM
Hi,
due to different register structure for exceptions and interrupts the functions have been separated: the SystemHandlerPriorityConfig() will work only for internal interrupt/exception sources, the NVIC_Init only for peripheral interrupts. See their allowed parameters (eg. in the NVIC header file) Although SysTick has got 8 bits in its own register, only 4 of them are considered. Your explanation of interrupt priority is correct, one more precision: if the preemption priority differs, the interrupt with lower number (higher priority) can preemp (''interrupt'') already running interrupt handler. If the int's differ only in SubPriority, they don't interrupt each other, but ''order'' themselves according to the subpriority.