STM32 Interrupt priorities and preemption
Hi,
I have a problem where I cannot get a higher priority interrupt to interrupt a lower priority one. My understanding is that this should 'just work' so I'd really appreciate your input on this... I've created a basic example which is designed to run on the STM32VLDISCOVERY board, but I've had the same issue with the F4 (and I imagine I would on other chips too)In the example, LED1 is flashed slowly by the SysTick interrupt, and LED2 is flashed by the main loop.
Expected outcome
When BTN1 is pressed, the EXTI0 interrupt is called, it flashes LED2 quickly until the higher priority SysTick interrupt is fired, and then it exits. The LED1 keeps on flashing as before.
Actual outcome
When BTN1 is pressed, the EXTI0 interrupt is called, it flashes LED2 quickly. The higher priority SysTick interrupt is never fired, LED1 never flashes and the LED2 continues to blink quickly.
#include ''stm32f10x.h''
typedef
char bool ; volatile bool toggle;void
delay( void ) { volatile int i = 100000; while (i-- > 0) { } } void delaySlow( void ) { volatile int i = 1000000; while (i-- > 0) { } }// Toggle LED1 on SysTick
void SysTick_Handler( void ) { if (toggle = !toggle) GPIO_SetBits(GPIOC, GPIO_Pin_8); else GPIO_ResetBits(GPIOC, GPIO_Pin_8); }// On EXTI IRQ, flash LED2 quickly, and wait for a SysTick
void EXTI0_IRQHandler( void ) { bool lastToggle = toggle; GPIO_SetBits(GPIOC, GPIO_Pin_9); while (lastToggle==toggle) { // wait for systick // Flash LED2 slowly GPIO_SetBits(GPIOC, GPIO_Pin_9); delay(); GPIO_ResetBits(GPIOC, GPIO_Pin_9); delay(); } GPIO_ResetBits(GPIOC, GPIO_Pin_9);EXTI_ClearITPendingBit(EXTI_Line0);
}int
main( void ){ GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |
RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE, ENABLE); // set preemption NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_Init(GPIOC, &GPIO_InitStructure); GPIO_Init(GPIOD, &GPIO_InitStructure); GPIO_Init(GPIOE, &GPIO_InitStructure); // button GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); // leds GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC, &GPIO_InitStructure); // systick SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); SysTick_Config(0xFFFFFF); // 24 bit NVIC_InitStructure.NVIC_IRQChannel = SysTick_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // Highest priority NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); // exti 0 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F; // Lowest priority NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; NVIC_Init(&NVIC_InitStructure); GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0); EXTI_InitTypeDef s; EXTI_StructInit(&s); s.EXTI_Line = EXTI_Line0; s.EXTI_Mode = EXTI_Mode_Interrupt; s.EXTI_Trigger = EXTI_Trigger_Rising; s.EXTI_LineCmd = ENABLE; EXTI_Init(&s);while
(1) { // Flash LED2 slowly GPIO_SetBits(GPIOC, GPIO_Pin_9); delaySlow(); GPIO_ResetBits(GPIOC, GPIO_Pin_9); delaySlow(); } }