AnsweredAssumed Answered

Troubles with priorities

Question asked by perez_maestro.miguel on Mar 9, 2016
Latest reply on Mar 11, 2016 by perez_maestro.miguel
Hi there, can anyone help me with this??


Im working with STM32f407.

The programm consists in switch on/off lights and change its intensity using dimmer.

A 50Hz wave is connected to a zero cross detector, and its output connected to a GPIO IN, used as EXTI Line interrupt. So each 10ms is executing the task into that EXTI_Handler.

This is how I configure the interrupt:

void Configure_ZCInterrupt() {
     GPIO_InitTypeDef GPIO_InitStruct;
     /* Enable clock for GPIO */
     RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
     GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8;
     GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
     GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
     GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
     GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
     GPIO_Init(GPIOD, &GPIO_InitStruct);


     EXTI_InitTypeDef EXTI_InitStruct;
     // Enable clock for SYSCFG
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
     SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB, EXTI_PinSource8);
     EXTI_InitStruct.EXTI_Line = EXTI_Line8;
     EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
     EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling;
     EXTI_InitStruct.EXTI_LineCmd = ENABLE;
     EXTI_Init(&EXTI_InitStruct);


     NVIC_InitTypeDef NVIC_InitStruct;
     // Add IRQ vector to NVIC
     NVIC_InitStruct.NVIC_IRQChannel = EXTI9_5_IRQn;
     NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x00;
     NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x00;
     NVIC_InitStruct.NVIC_IRQChannelCmd = DISABLE;
     NVIC_Init(&NVIC_InitStruct);
}

And this is the handler:

void EXTI9_5_IRQHandler() {

     
     if (EXTI_GetITStatus(EXTI_Line8) != RESET) {
          uint8_t num = 0;

          if (screen.LIGHTS[0].status == ACTIVE) {
               num = 1;
               Delay_ms(1 + screen.LIGHTS[0].dimmer * 1);
               Set_Light(&screen, &num);
               Delay_ms(1);
               Reset_Light(&screen, &num);


          }

     EXTI_ClearITPendingBit(EXTI_Line8);
}


In other hand, I have a timer running and if a screen is not touched for 40seconds, an update interrupt of that timer will be dispatched.

This is the timer config:
void Init_EnergySaveTimmer(void) {


     TIM_TimeBaseInitTypeDef timerInitStructure;


// TIM1 Configuration
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
     timerInitStructure.TIM_Prescaler = 0xffff; //timer_tick_frequency = 168000000 / 65536 = 2563.51 Hz --> 0.39 ms
     timerInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
     timerInitStructure.TIM_Period = 0xFFFF; // Se desbordará cada 60000 x 0.39 = 23.4 s
     TIM_TimeBaseInit(TIM1, &timerInitStructure);
     TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);
     TIM_Cmd(TIM1, ENABLE);


     NVIC_InitTypeDef NVIC_InitStructure;
// Enable the TIM1 Interrupt
     NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_TIM10_IRQn;
     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
     NVIC_Init(&NVIC_InitStructure);
}

and it is its update handler:

void TIM1_UP_TIM10_IRQHandler() {


     if (TIM_GetITStatus(TIM1, TIM_IT_Update) == SET) {


          if (idleState == 0) {
                    LCD_Clear(Black, 1);
                    Chk_Busy();
                    print_BTERecic();
                    Wait_ms(1200);
                    TM_RTC_Interrupts(TM_RTC_Int_60s);
                    LCD_Clear(Black, 1);
                    Chk_Busy();
                    Display_OFF();
                    Wait_ms(10);
                    BackLight_DeInit();
                    Wait_ms(100);
                    idleState = 1;

          }

          TIM_ClearITPendingBit(TIM1, TIM_IT_Update);
     }

}

The difference between delay_ms() and wait_ms() is as follows:

Delay config and handler:

void TimerDelay_Init(void) {
     TIM_TimeBaseInitTypeDef Timer_InitStructure;
     NVIC_InitTypeDef NVIC_InitStruct;


     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);


     Timer_InitStructure.TIM_Prescaler = 83; // 1 us
     Timer_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;
     Timer_InitStructure.TIM_Period = 999;
     Timer_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
     Timer_InitStructure.TIM_RepetitionCounter = 0;


     /* Initialize TIM5 */
     TIM_TimeBaseInit(TIMERDELAY, &Timer_InitStructure);


     /* Enable interrupt each 1ms */
     //TIM_ITConfig(TIMERDELAY, TIM_IT_Update, ENABLE);
     /* Set NVIC parameters */
     NVIC_InitStruct.NVIC_IRQChannel = TIM5_IRQn;
     NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
     NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
     NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;


     /* Add Timer to NVIC */
     NVIC_Init(&NVIC_InitStruct);


     /*Start Timer */
     TIM_Cmd(TIM5, ENABLE);
}
void Delay_ms(uint32_t ms) {

     volatile uint32_t timer = TIM_GetCounter(TIM5);


     uint32_t milis = ms * 1000;
     do {
          /* Count timer ticks */
          while ((TIM5->CNT - timer) == 0)
               ;


          /* Increase timer */
          timer = TIM5->CNT;


          /* Decrease microseconds */
     } while (--milis);
}


void TIM5_IRQHandler(void) {


     TIM_ClearITPendingBit(TIM5, TIM_IT_Update);


     uint8_t i;


     Time1++;
     if (Time2 != 0x00) {
          Time2--;
     }


     /* Call user function */
     MILI_Handler();
}



Wait config and handler:



void TimerWait_Init(void) {


     TIM_TimeBaseInitTypeDef timerInitStructure;


     // TIM3 Configuration
     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
     timerInitStructure.TIM_Prescaler = 8399; //timer_tick_frequency = 84000000 / (8399+1) = 10 KHz --> 100 us
     timerInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
     timerInitStructure.TIM_Period = 0xffff;
     timerInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
     timerInitStructure.TIM_RepetitionCounter = 0;
     TIM_TimeBaseInit(TIM3, &timerInitStructure);
     TIM_ITConfig(TIM3, TIM_IT_Update, DISABLE);
     TIM_Cmd(TIM3, ENABLE);


}
 void Wait_ms(uint32_t ms) {
     TIM_Cmd(TIM3, ENABLE);
     TIM_SetCounter(TIM3, 0);


     uint32_t *contador;
     uint32_t milis = ms * 10;
     contador = &TIM3->CNT;
     while (TIM3->CNT < milis) {
     }
}


Due to the priorities, EXTI_9_5_Handler, should be executing each 10ms, but its not working like that.

When TIM1 (EnergySaveTimer) updates, EXTI_9_5_Handler, is not executing while wait_ms() is executing, but i dont understand why, becouseseach 10ms, should be called, but it is not. Can anyone tell me whats wrong here??


Thanks in advance

Outcomes